是什么原因导致这个列表在被单向调用时通过引用传递,但是按值传递另一个?

时间:2013-06-26 21:08:51

标签: c#

我正在进行一项运行验证方法的简单测试,并遇到了这种奇怪的情况。

public IEnumerable<int> ints (List<int> l)
{
 if(false)yield return 6;
 l.Add(4);
}


void Main()
{
 var a = new List<int>();
 var b = new List<int>();
 for( int i = 0; i < 4; i++ ){
  a.Add(i);
  b.Add(i);
 }
 a.AddRange(ints(a));
 ints(b);
 Console.WriteLine(a);
 Console.WriteLine(b);
}

此代码运行后,a将包含[0,1,2,3,4]。但是,b将包含[0,1,2,3]。为什么在AddRange中将方法作为参数调用允许列表通过引用传递?或者,如果没有发生,那做了什么?

1 个答案:

答案 0 :(得分:15)

ints(b)调用不会枚举IEnumerable,因此代码永远不会到达l.Add(4)行,这与AddRange枚举所有项目以将其添加到列表中的情况不同。

要查看它,请手动调用b案例枚举结果:

ints(b).ToList();
通过函数实现的

IEnumerable<T>在枚举开始之前不执行函数体 - 代码实际上由编译器转换为具有状态的类,以支持可枚举的真正延迟评估(详细信息可以在多篇文章中找到,即Iterator Pattern demystified - Tim Schmelter提供的链接。)