Skip to main content
 首页 » 编程设计

c#之为什么集合赋值在方法和连续行中的行为不同

2024年02月06日25daizhj

From the below results, I like to know why 'Test 2' have value as 30 , I expect the same result as in 'Test 3' (100) ?

这是 fiddler 链接 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 

请您参考如下方法:

在第二次测试之前,您将 initialCollection 中值的副本传递给 UpdateValueCollection,在该方法中您忽略传递的值,创建一个新列表,然后然后修改该列表。此方法永远不会对该方法的任何调用者产生任何可观察到的影响。

在测试 3 之前,您创建一个新列表,为其赋值,然后将其分配给 initialCollection,改变该变量的值。由于您更改了此变量的值,与您的第二次测试不同,当您稍后获取该变量的值时,它会产生可观察到的效果。

UpdateValueCollection 方法是否通过引用 传递了参数(通过使用 ref 或 out 关键字) 而不是按值,那么对参数的更改也会影响 initialCollection,但由于它是按值传递的,因此只有变量的副本发生了变化。

请注意,如果您真的希望 UpdateValueCollection 为您的变量计算一个新列表,则更符合惯用的设计是让 UpdateValueCollection 返回一个新列表 而不是 void,然后将该方法的值赋给 initialCollection。