从下面的结果中,我想知道为什么'测试2'的值为30, 我期望与“测试3”(100)中的结果相同?
以下是提琴手链接https://dotnetfiddle.net/Rco1mD以便更好地理解。
IList<Test> initialCollection = new List<Test>();
initialCollection.Add(new Test(){ Value = 30});
Console.WriteLine("Test 1 : Before update method : " + initialCollection.Last().Value );
UpdateValueCollection(initialCollection);
Console.WriteLine("Test 2: After update method : " + initialCollection.Last().Value );
IList<Test> check = new List<Test>();
check.Add(new Test(){ Value = 100});
initialCollection = check;
Console.WriteLine("Test 3: Same update method code added as consecutive line : " + initialCollection.Last().Value );
我的另一种方法是
public void UpdateValueCollection(IList<Test> lstTest)
{
IList<Test> check = new List<Test>();
check.Add(new Test(){ Value = 100});
lstTest = check;
}
结果
Test 1 : Before update method : 30
Test 2 : After update method : 30
Test 3 : Same update method code added as consecutive line : 100
答案 0 :(得分:3)
在第二次测试之前,您将initialCollection
中的值的副本传递给UpdateValueCollection
,在该方法中,您忽略传递的值,创建新列表,然后修改该列表。此方法永远不会对此方法的任何调用者产生任何可观察到的影响。
在测试3之前,您创建一个新列表,为其赋值,然后将其分配给initialCollection
,改变该变量的值。由于您更改了此变量的值,因此与第二次测试不同,当您稍后获取该变量的值时,它会产生可观察的效果。
如果方法UpdateValueCollection
通过参考(通过使用ref
或out
关键字)而不是按值<传递参数 / em>,然后对参数的更改也会影响initialCollection
,但是当它按值传递时,只变量的副本被突变。
请注意,如果您真的希望UpdateValueCollection
为您的变量计算新列表,则更为惯用的设计是UpdateValueCollection
返回新列表而不是{ {1}},然后将该方法的值分配给void
。
答案 1 :(得分:1)
当您在lstTest = check;
内致电UpdateValueCollection
时,您只更新该方法中可见的参考lstTest
,您需要通过引用传递lstTest
才能更换列表本身并在UpdateValueCollection
方法之外可见:
public void UpdateValueCollection(ref IList<Test> lstTest)
{
IList<Test> check = new List<Test>();
check.Add(new Test(){ Value = 100});
lstTest = check;
}
答案 2 :(得分:0)
这些“奇怪”的事情可能会发生,因为你给你的方法一个IList的引用。如果现在更改IList的值,则仅在此方法中更新引用。 这意味着你现在可以在RAM的其他部分玩。
要解决此问题,您必须更改对IList引用的引用。 喜欢这个
public void UpdateValueCollection(ref IList<Test> lstTest)
{
IList<Test> check = new List<Test>();
check.Add(new Test(){ Value = 100});
lstTest = check;
}