'private static readonly'字段和静态/非静态构造函数

Hel*_*ele 3 c# modifier

我有三个对象:

private static readonly Apple a, c;
private readonly Orange b;
Run Code Online (Sandbox Code Playgroud)

从我的构造函数调用此代码:

public SomeClass()
{
    a = new Apple();
    b = new Orange(a.getDna());
    c = new Apple(b.getDna());
}
Run Code Online (Sandbox Code Playgroud)

它给了我错误Readonly field cannot be used as an assignment target.如果我删除static readonly修饰符,它会完美编译.(这里有错误的警告吗?)

在SO上检查其他答案时,我发现我应该使用静态构造函数,如:

static SomeClass()
{
    a = new Apple();
    c = new Apple(b.getDna());
}

public SomeClass()
{
    b = new Orange(a.getDna());
}
Run Code Online (Sandbox Code Playgroud)

但是这会导致首先调用静态构造函数并导致错误,因为b不会被初始化.

我该如何规避这个?

PS我对C#比较新

Jcl*_*Jcl 6

让我们从定义成员static之间的区别staticinstance成员之间的区别开始.

静态成员是不需要存在实例的成员:它"属于类",而不是对象(类的实例).

现在readonly修饰符说,成员只能在构造函数中(或在其声明中,但在此处不相关)中赋值.

有两种类型的构造函数:静态构造函数和实例构造函数......差异与上面的差异相同,readonly修饰符当然适用于每种类型的构造函数:static readonly意思是"你只能在静态中改变它的值"构造函数",实例readonly将意味着"您可以在实例构造函数中更改其值".

静态构造函数在第一次访问类型时被调用,因此它始终首先被调用.

现在,在示例中,您只是随意更改成员,static或者只是尝试编译.

考虑一下......在static上下文中你根本就没有实例,所以在static构造函数上访问实例成员是不可能的......而且,在调用静态构造函数时,你无法做到有任何初始化的实例,甚至是外部定义的,因为它总是在你有机会初始化之前被调用.

所以静态构造函数中的这一行毫无意义:

c = new Apple(b.getDna());
Run Code Online (Sandbox Code Playgroud)

您正在尝试访问b,这是一个实例成员,但您不是说应该从哪个实例获取值.

你应该重新考虑你的设计,并思考为什么成员会是静态的,而不仅仅是"移动并尝试使其编译和运行".