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; }
}
Related
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 is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I'm encountering a problem when I try to fill a List of List of strings. (Each List represents a page to print, with each string in the list being a line of text on a page). The List of List of Strings represents the entire text of a document. I need this List<List<string>> so I can pair each document with it's respective Config File.
I'm going to copy the relevant code here:
Here's my Variables and the accessor and mutator I use for my List<List<string>>
private static readonly TemplateSingleton instance = new TemplateSingleton();
private List<string> lineOfPage;
private List<List<string>> _streamList;
public List<List<string>> StreamList
{
get { return _streamList; }
set { value = _streamList; }
}
And here's the method that's breaking:
#region Generate Lists
//Takes the stream of data and adds it to a list that can be processed.
public void GenerateLists(ref List<List<string>> arg, ReportConfig cfg)
{
if (TemplateSingleton.Instance.CurrentReportNum == 0)
{
TemplateSingleton.Instance.CFGList = new List<ReportConfig>();
TemplateSingleton.Instance.ReportsList = new List<Templates>();
}
TemplateSingleton.Instance.CFGList.Add(cfg);
TemplateSingleton.Instance.ReportsList.Add(TemplateSingleton.Instance.ChooseTemplate(cfg));
if (StreamList == null)
{
//Create a list of array values to hold them.
StreamList = new List<List<string>>(arg.Count);
}
int counter = 0;
foreach (List<string> argString in arg)
{
//Build a new array with the size equal to the number of lines.
lineOfPage = new List<string>();
//If the string isn't null...
if (argString != null)
{
//for each line of each page...
foreach (string str in argString)
{
//...If *that* string isn't null...
if (str != null)
{
//...add the string to the array of lines on a page.
lineOfPage.Add(str);
}
}
//list.Add(lineOfPage);
//A lot to unpack here. Add each line of a page, where the line of a page isn't empty, as an array, then convert the result back to a list.
StreamList.Add(new List<string>(lineOfPage.ToArray().Where(x => !string.IsNullOrEmpty(x)).ToList()));
}
//Add the list to my List of Lists
TemplateSingleton.Instance.ListOfStringLists.Add(StreamList);
}
When I run the code, my other lists initialize just fine. But when it tries to do
StreamList.Add(new List<string>(lineOfPage.ToArray().Where(x => !string.IsNullOrEmpty(x)).ToList()));
It breaks. It's not the LINQ I use, either. When I run it as just
StreamList.Add(argString);
I get the same error. I've tried a lot of different things. The exact location of the error (that I can see) is that when the line that initializes my StreamList (StreamList = new List>()) executes, it doesn't actually initialize. In fact, it still shows as having a value of null (when I step through the method.)
I've only been coding for a couple months now. I've learned a lot of cool things but there are properties about vars that I use (like List) that might have limitations I'm unfamiliar with. I'd appreciate any help you all can offer. Thanks!
Edit: This question has been answered. It was a silly typo that broke it. If anyone has the same problem, I'll post the updated code that works.
private static readonly TemplateSingleton instance = new TemplateSingleton();
private List<string> lineOfPage;
private List<List<string>> _streamList;
public List<List<string>> StreamList
{
get { return _streamList; }
set { _streamList = value; }
}
Or
public List<List<string>> StreamList { get; set; } //Automatically implemented property.
Thanks for the help!
Check out the setter:
set { value = _streamList; }
This should be
set { _streamList = value; }
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.
This question already has answers here:
C# preventing Collection Was Modified exception
(10 answers)
Closed 8 years ago.
Here's an easy one for one of you smart folks -- I have an observable collection containing viewmodel objects. I'm trying to go through the objects and remove any where the plant.Living property is "No". I am using this code:
foreach (PlantViewModel plant in Plants)
{
if (plant.Living == "No")
{
Plants.Remove(plant);
}
}
PlantsViewSource.Source = Plants;
PlantsGridView.SelectedItem = null;
However, when the first object is encountered that meets the criteria and that object is removed, it modifies the collection and the foreach throws an error. How can I remove the objects from the collection in another way?
As the error tells you, you can't remove an item from a collection you're enumerating. An answer is to keep a list of the items you want to remove.
List<PlantViewModel> plantsToRemove = new List<PlantViewModel>();
foreach (PlantViewModel plant in Plants)
{
if (plant.Living == "No")
{
plantsToRemove.Add(plant);
}
}
foreach(var plant in plantsToRemove)
Plants.Remove(plant);
PlantsViewSource.Source = Plants;
PlantsGridView.SelectedItem = null;
A more readable option is;
List<PlantViewModel> plantsToRemove = Plants.Where(p => p.Living == "No");
foreach(var plant in plantsToRemove)
Plants.Remove(plant);
PlantsViewSource.Source = Plants;
PlantsGridView.SelectedItem = null;