Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following loop:
List<Reminders> reminds = new List<Reminders>();
//...
foreach (Reminders remind in reminds)
{
//....
reminds.Insert(id, new Reminders() { Title = remind.Title, Content = remind.Content, Checked = true });
}
However, an error occurs in the foreach loop.
foreach (Reminders remind in reminds)
If I remove the reminds.Insert statement, the error no longer occurs. I'm trying to update some entires inside of the foreach loop. What's causing the error?
Change your Code to this:
List<Reminders> reminds = new List<Reminders>();
...
foreach (Reminders remind in reminds.ToList())
{
....
reminds.Insert(id, new Reminders() { Title = remind.Title, Content = remind.Content, Checked = true });
}
Please note the .ToList() behind reminds.
Explanation: You are not allowed to modify a collection while it is enumerated in an foreach. The .ToList() will create another temporary collection which will be constrant during the foreach loop.
It's true, you are iterating in the same list. You need to create a temporary list, and add the elements in that temp list in the cycle. After, when the foreach finish, you need to use the method AddRange:
reminds.AddRange(tempList);
If you want to update some entries then you shoudn't add new ones just set the property Checked to true of each entry:
List<Reminders> reminds = new List<Reminders>();
...
foreach (Reminders remind in reminds)
{
....
remind.Checked = true;
}
You must not modify the list that you are iterating.
No, You can't insert into an item while iterating through it. Your results will be wrong.
You will need to create a temporary list and do an AddRange() after.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
How to increase performance (it takes about 10 seconds) of this foreach loop
foreach (var item in pList)
{
var foundedItem = source.FirstOrDefault(x => x.LongRecordId == item.LongRecordId);
if (foundedItem != null && !selectionList.Contains(foundedItem))
{
foundedItem.Readonly = pReadonly;
selectionList.Add(foundedItem);
}
}
In case source as well as pList are long, you may try converting source into a Dictionary:
// Provinding that all LongRecordId are distinct
var dict = source
.ToDictionary(item => item.LongRecordId, item => item);
...
foreach (var item in pList) {
MyRecord foundItem = null; //TODO: Put the right type here
// Instead of O(N) - FirstOrDefault we have O(1) TryGetValue
if (dict.TryGetValue(item.LongRecordId, out foundItem)) {
foundItem.Readonly = pReadonly;
selectionList.Add(foundItem);
}
}
Edit: In case you want to ensure that selectionList contains distinct items only (see Ferhat Sayan's comment) try HashSet
...
HashSet<MyRecord> selectedHash = new HashSet<MyRecord>(selectionList);
foreach (var item in pList) {
MyRecord foundItem null; //TODO: Put the right type here
// Instead of O(N) - FirstOrDefault we have O(1) TryGetValue
if (dict.TryGetValue(item.LongRecordId, out foundItem)) {
foundItem.Readonly = pReadonly;
selectedHash.Add(foundItem);
}
}
selectionList = selectedHash.ToList();
I suggest to profile that piece of code.
I guess the most time consuming call is the FirstOrDefault-Extension Method.
To use for instead of foreach is unlikely to grant you much if any performance gains.
Most probably your problems stems from your context variables, maybe a very large source list?
Overall, this code section is maybe not the best place to look for performance improvements. If this is the only place, you should think about a redesign.
If you have very large lists and do not fear concurrency issues you could go the parallel or multi-processing route. parallel.foreach is a cheap way to do some tests.
The use of a Dictionary instead of a List should speedup things. If you go with a HashSet (to yield the benefit of uniqunes) be aware to implement a proper IEqualityComparer, or you could even lose performance when you add a huge number of items relying on the DefaultComparer.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So i have a let's say 100 statements in C#.
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU01_IEmergOpenAct.Force(false);
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU02_IEmergOpenAct.Force(false);
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU03_IEmergOpenAct.Force(false);
And so on till DCU100. I want to run a loop in that way that I can access all the statements DCU01..DCU100.
EDIT : Everything before Force. is a signal container. That's why can't use Array or List (No overload method).
You can use reflection
var obj = CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst;
for(int i = 0; i < yourCount; i++){
var prop = obj.GetType().GetProperties().FirstOrDefault(x => x.Name == string.Format("DCU{0}_IEmergOpenAct", i));
if(prop != null){
var propValue = (YourObjectType)prop.GetValue(CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst);
propValue.Force(False);
}
}
Maybe you need to format the i variable to "00" or something in the string.Format() call
If CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU01_IEmergOpenAct is a type name (instead of a member), then you can try the following approach:
IEnumerable<MethodInfo> methods =
Enumerable.Range(1, 100)
.Select(i => $"CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU{i:D2}_IEmergOpenAct")
.Select(t => Type.GetType(t))
.Select(t => t.GetMethod("Force", BindingFlags.Public | BindingFlags.Static));
foreach (MethodInfo force in methods)
force.Invoke(null, new object[] { false });
Option 1
Useful if you don't mind writing the whole list once and need it multiple times.
Put it into all individual items into a List/Array and loop over it.
var list = new List<IEmergOpenAct>() { // I am guessing a type here
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU01_IEmergOpenAct,
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU02_IEmergOpenAct,
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU03_IEmergOpenAct,
};
foreach (var act in list)
{
act.Force(false);
}
Option 2
Useful if you don't want to type the whole list but they follow a unique pattern.
Open the Type/Namespace DRSa09_DrEmrgOpnCst via Reflection and get all Types that match the "DCU??_IEmergOpenAct" pattern. Put them into a list like in option 1 and loop over them as shown above.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a list of objects in which I want to remove duplicates but does not want to remove blank objects.
I am using DistinctBy lambda expression. But it also removes duplicates.
Can anyone help me in providing the condition that passes blank and checks only that object which has proper value in an object ?
You could use a very simple extension method:
public static void DistinctKeepingEmptyStrings(this List<string> list) {
var support = new List<string>(list);
HashSet<string> knownValues = new HashSet<string>();
foreach (var aString in list) {
if (aString == "" || knownValues.Add(aString)) {
support.Add(aString);
}
}
list.Clear();
list.AddRange(support);
}
Example:
var list is in this case a list consisting of all duplicates (minus the empty strings)
then I just iterate through the duplicates and remove them from the listOfValues.
List<string> listOfValues = new List<string> {"test", "test2", "", "test2", "", ""};
var list = listOfValues.GroupBy(r => r).SelectMany(grp => grp.Skip(1)).Where(r => r != "");
foreach (var aVar in list)
{
listOfValues.Remove(aVar);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have one original list and two temporary lists.
Based on certain condition, I am adding data from the original list(after modifying certain values) to these temp lists. But changes made in one temp list via this copy operation is updating the other temp list as well.
List<UserLMSSubFunc> lstUserLMSSubFunc = null;
List<UserLMSSubFunc> lstUserLMSSubFuncTemp1 = new List<UserLMSSubFunc>();
List<UserLMSSubFunc> lstUserLMSSubFuncTemp2 = new List<UserLMSSubFunc>();
foreach (Constructor subFnc in originalList)
{
foreach (KeyValuePair<string, string> kv in OriginalList)
{
if (kv.Value.ToUpper() == subFnc.SubFuncCode.ToUpper())
{
if (subFnc.FuncCode == null)
{
subFnc.FuncCode = kv.Key;
templist1.Add(subFnc);
}
else
{
subFnc.FuncCode = kv.Key;
Templist2.Add(subFnc);
}
}
}
}
The reason why the data in your lists is changing is due to the reference / value type mishmash. Your lists hold only a reference to an object inside that list. Therefore whenever you change your object which you have pulled from one of the lists I suspect it is the same object which is located in the other two as well, hence the change which seemingly propagates itself across the lists.
Use Setter
private var temp1 = new List<Package>();
public List<Package> temp1
{
set { temp1 = value;
update your temp2}
get { return temp1; }
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I created Class Disk
Disk disk1 = new Disk();
Hashtable myCatalog = new Hashtable();
try
{
myCatalog.Add("Disk1", disk1);
}
catch
{
Console.WriteLine("An element with Key = \"Disk1\" already exists.");
}
Disk valueColl = (Disk)myCatalog.Values;
valueColl.
And here I have a problem.
How I can use this method ShowCompositions();
Values is a ICollection containing the values in the Hashtable.
You could do this.
Disk valueColl = (Disk)myCatalog["Disk1"]; // access element with `Key`
valueColl.ShowCompositions(); // this will work
On other note as #jamesthorpe highlighted in comments , try using Dictionary over Hashtable, it has added advantages.
Easiest way
Hashtable hashtable = new Hashtable();
foreach (DictionaryEntry entry in hashtable)
{
Console.WriteLine("{0}, {1}", entry.Key, entry.Value);
}