views:

103

answers:

2

I have the following sample codes. I don't like to have lTest being captured and get the same value as lRet. I tried to introduce "List<Test> lTest1 = lTest0;" in the function AddMore2Test. It does not work. What is the proper way to do this?

Thanks!

Codes -

private void Test(){
  List<Test> lTest = GetInitTestList();

  List<Test> lRet = AddMore2Test(lTest);
}

private List<Test> AddMore2Test (List<Test> lTest0) {
  List<Test> lTest1 = lTest0;

  return lTest1.Where(…);
}
+3  A: 

So at the end of it all you want lTest to contain an initial set of values, and lRet to contain those initial values, but with a bit of filtering applied? The problem is you are dealing with references, so ultimately everything is pointing at the same list. A quick, simple fix is to just do this:

List<Test> lRet = AddMore2Test(lTest.ToList());

Matt Greer
+1 - I could not understand the question, but how in the heck someone else did is beyond me. :)
JonH
But my answer doesn't really work, since AddMore2Test returns a List, and he is using LINQ, he has to be calling ToList() on the IEnumerable LINQ gave him, so he should have two distinct lists already.
Matt Greer
Passing lTest.ToList() gets me the desired short list lRet. lRet and lTest seems not point to the same list. But after I change some fields in an item of lRet. The corresponding fields in lTest change to the same value also. Does each underneath item in lRet and lTest still point to each other? If so, how to solve this problem?
Don
Yes, a list is just a collection of references. So when you create a new list against an existing one, both lists will point to the same objects (unless the objects are value types). If you want two distinct lists each with their own distinct objects, then you will need to roll that yourself. Look into `IClonable` as a start (although that has drawbacks). I also recommend sitting down with a good C# book and really understanding how references work, that will help reduce a lot of confusion.
Matt Greer
+2  A: 

I think you will probably want to use the List class' AddRange(IEnumerable list) method on the lRet instead of assinging the value:

lRet.AddRange(AddMore2Test(lTest))

EDIT: in the comments it was pointed out that lRet hadn't yet been initialized, so here is a viable change:

var lRet = new List<Test>(AddMore2Test(lTest));
Josh E
lRet is not initialized, so he can't call methods on it. But he could do `lRet = new List<Test>(lTest); lRet.AddRange(AddMore2Test(lTest));`
Matt Greer
ahh yes good catch. Even more compact would be lRet = new List<Test>(AddMore2Test(lTest)); though that may not be as readable
Josh E