c#:全局变量值已更改,即使它没有在循环中分配新值
c#: Global variable value changed even though it doesn't be assigned new value in a loop
谁能帮忙解释一下为什么会得到这个结果?我期望的结果是“1,2”。
var list1 = new List<int> { 1, 2 };
List<List<int>> listStrs = new List<List<int>> { new List<int>{100,101 }, new List<int>{ 200, 201 } };
foreach (var listStr in listStrs)
{
List<int> list2 = list1; //the way try to get expected result: List<int> list2 = list1.Select(i => i).ToList();
list2.AddRange(listStr);
}
Console.WriteLine(String.Join(",",list1));
//结果return: 1,2,100,101,200,201
List<T>
是 引用类型 。当您执行以下操作时:
List<int> list2 = list1;
你实际上在做的是告诉编译器复制变量 list1
的值并将其分配给 list2
。您必须了解变量只是 值 的占位符。在引用类型中,变量的 value 是对象“所在”的“内存地址”。因此,list2
和 list1
都“指向”(或引用)完全相同的对象;有两个变量,但只有一个列表。
这很明显,只需做:object.ReferenceEquals(list1, list2)
。它将 return true
.
List<int> list2 = list1.Select(i => i).ToList();
如您所愿,因为投影 (Select
) 创建了一个 new 列表。这个新列表和 list1
是完全不同的实例,每个都“生活”在不同的内存位置并且完全无关; object.ReferenceEquals(list1, list2)
将 return false
.
现在,请记住,事情随着值类型而改变。值类型变量中“存储”的值是实例本身;没有涉及值类型的引用(除非它们被装箱)。
因此,代码如下:
struct EvilMutableStruct
{
public int i
}
var e1 = new EvilMutableStruct();
var e2 = e1;
e2.i = 1;
Console.WriteLine(e1.i == 1); //prints false!
为什么?因为,e2 = e1
的意思是一样的;复制存储在 e1
中的值并将其分配给 e2
。因为 e1
的值是值类型实例本身,所以会制作对象的副本并将其存储在 e2
中。现在两个值类型变量都包含两个相同但 不同 值类型实例。
谁能帮忙解释一下为什么会得到这个结果?我期望的结果是“1,2”。
var list1 = new List<int> { 1, 2 };
List<List<int>> listStrs = new List<List<int>> { new List<int>{100,101 }, new List<int>{ 200, 201 } };
foreach (var listStr in listStrs)
{
List<int> list2 = list1; //the way try to get expected result: List<int> list2 = list1.Select(i => i).ToList();
list2.AddRange(listStr);
}
Console.WriteLine(String.Join(",",list1));
//结果return: 1,2,100,101,200,201
List<T>
是 引用类型 。当您执行以下操作时:
List<int> list2 = list1;
你实际上在做的是告诉编译器复制变量 list1
的值并将其分配给 list2
。您必须了解变量只是 值 的占位符。在引用类型中,变量的 value 是对象“所在”的“内存地址”。因此,list2
和 list1
都“指向”(或引用)完全相同的对象;有两个变量,但只有一个列表。
这很明显,只需做:object.ReferenceEquals(list1, list2)
。它将 return true
.
List<int> list2 = list1.Select(i => i).ToList();
如您所愿,因为投影 (Select
) 创建了一个 new 列表。这个新列表和 list1
是完全不同的实例,每个都“生活”在不同的内存位置并且完全无关; object.ReferenceEquals(list1, list2)
将 return false
.
现在,请记住,事情随着值类型而改变。值类型变量中“存储”的值是实例本身;没有涉及值类型的引用(除非它们被装箱)。
因此,代码如下:
struct EvilMutableStruct
{
public int i
}
var e1 = new EvilMutableStruct();
var e2 = e1;
e2.i = 1;
Console.WriteLine(e1.i == 1); //prints false!
为什么?因为,e2 = e1
的意思是一样的;复制存储在 e1
中的值并将其分配给 e2
。因为 e1
的值是值类型实例本身,所以会制作对象的副本并将其存储在 e2
中。现在两个值类型变量都包含两个相同但 不同 值类型实例。