C#的yield关键字由来以久,如果我没有记错的话,应该是在C# 2.0中被引入的。相信大家此关键字的用法已经了然于胸,很多人也了解yield背后的“延迟赋值”机制。但是即使你知道这个机制,你也很容易在不经意间掉入它制造的陷阱。
目录
一、一个很简单的例子
二、简单谈谈“延迟赋值”
三、从反射的代码帮助我们更加直接的了解yield导致的延迟赋值
四、如果需要“立即赋值”怎么办?
后记
下面是一个很简单的例子:Vector为自定义表示二维向量的类型,Program的静态方法GetVetors方法获取以类型为IEnumerable<Vector> 表示的Vector列表,而方法通过yield关键字返回三个Vectior对象。在Main方法中,将GetVetors方法的返回值赋值给一个变量,然后对每一个Vector对象的X和Y进行重新赋值,最后将每一个Vector的信息输出来。从最后的输出我们不难看出,我们对Vector的重新赋值无效,最终的每一个Vector元素依旧“保持”着初始值。
class Program
{
static void Main(string[] args)
{
IEnumerable<Vector> vectors = GetVectors();
foreach (var vector in vectors)
{
vector.X = 4;
vector.Y = 4;
}
foreach (var vector in vectors)
{
Console.WriteLine(vector);
}
}
static IEnumerable<Vector> GetVectors()
{
yield return new Vector(1, 1);
yield return new Vector(2, 3);
yield return new Vector(3, 3);
}
}
public class Vector
{
public double X { get; set; }
public double Y { get; set; }
public Vector(double x, double y)
{
this.X = x;
this.Y = y;
}
public override string ToString()
{
return string.Format("X = {0}, Y = {1}", this.X, this.Y);
}
}