Lio*_*nAM 3 c# ienumerable yield-return
我只是注意到,通过yield return返回的静态成员的初始化不是按照它们枚举的顺序,而是以相反的顺序.虽然C1实例作为迭代器的第一项返回,但首先创建C2实例.如果产生超过2个项目,则最后一个项目首先被初始化.
public abstract class B
{
private static int _number;
protected B()
{
Number = ++_number;
}
public int Number { get; private set; }
}
class C1 : B
{
public static readonly C1 Default = new C1();
}
class C2 : B
{
public static readonly C2 Default = new C2();
}
public static IEnumerable<B> GetItems()
{
yield return C1.Default;
yield return C2.Default;
}
private static void Main(string[] args)
{
var items = GetItems();
foreach (var item in items)
{
Console.WriteLine(item.Number);
}
}
Run Code Online (Sandbox Code Playgroud)
根据问题评论,静态初始化并不总是确定性的.但是,您可以使用静态构造函数使其具有确定性:
class C1 : B
{
static C1(){}
public static readonly C1 Default = new C1();
}
class C2 : B
{
static C2(){}
public static readonly C2 Default = new C2();
}
Run Code Online (Sandbox Code Playgroud)
这迫使每一个C1和C2初始化恰好在第一次参考时 - 不早于那个,也不晚于那个.(其中"在第一次引用时"被定义为构造实例或访问静态成员.)
如果没有静态构造函数,类型初始化可能是急切的(即在您第一次使用类型之前发生)或者出乎意料地迟到.您可以创建实例,在类型上调用静态和实例方法,但仍然不运行静态字段初始值设定项 - 仅当您引用静态字段时必须运行静态字段初始值设定项.