0

Those are my old Code that cannot response correct result.

IList<string> testList=new List<string>();
testList.Add("string1");
var testList2=new List<string>(testList);
testList.ToList().AddRange(testList2);

I expect there are two elements in testList,but in fact it only have one; If i change my to code to new style ,its can get the right result.Example :

IList<string> testList=new List<string>();
testList.Add("string1");
var testList2=new List<string>(testList);
var result=testList.ToList();
result.AddRange(testList2);

In result,it successfully have two elements.I guess the reason is iList().toList() create a new List in other place,as param result,that is independent from iList(). Is it right? or other reasons?

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Moises .Li
  • 45
  • 4

2 Answers2

1

All the extension methods that come with System.Linq namespace create a new copy of the object (deep copy, if you will). So, you are right when you say that a new list is created at another memory location.

To confirm whether two objects are different, you can get their memory addresses via unsafe and see for yourself. Here is something to test (be cautious if you are using unsafe code; you need to handle all the memory management yourself):

unsafe
            {
                IList<string> testList = new List<string>();
                testList.Add("string1");
                var testList2 = new List<string>(testList);
                testList.ToList().AddRange(testList2);

                TypedReference original = __makeref(testList);
                IntPtr originalPointer = **(IntPtr**)(&original);

                var isThisANewList = testList;

                TypedReference newReferenceOnly = __makeref(testList);
                IntPtr newReferenceOnlyPointer = **(IntPtr**)(&newReferenceOnly);

                var copy = testList.ToList();

                TypedReference deepCopy = __makeref(copy);
                IntPtr deepCopyPointer = **(IntPtr**)(&deepCopy);
            }
danish
  • 5,550
  • 2
  • 25
  • 28
1

ToList() is an extension method that returns a list. You aren't holding that value in a variable, so although you call AddRange(), you are adding to the list you created in ToList() not to your testList.

In your second example, you are correctly holding the value of ToList() in result.

var result=testList.ToList();
result.AddRange(testList2);

You have a couple of options...

// option 1 declare testList as a List not IList
List<string> testList = new List<string>();
testList.AddRange(testList2);

// option 2 cast testList as a List
((List<string>)testList).AddRange(testList2);
reckface
  • 5,678
  • 4
  • 36
  • 62