我有三个对象:
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#比较新
让我们从定义成员static之间的区别static和instance成员之间的区别开始.
静态成员是不需要存在实例的成员:它"属于类",而不是对象(类的实例).
现在readonly修饰符说,成员只能在构造函数中(或在其声明中,但在此处不相关)中赋值.
有两种类型的构造函数:静态构造函数和实例构造函数......差异与上面的差异相同,readonly修饰符当然适用于每种类型的构造函数:static readonly意思是"你只能在静态中改变它的值"构造函数",实例readonly将意味着"您可以在实例构造函数中更改其值".
静态构造函数在第一次访问类型时被调用,因此它始终首先被调用.
现在,在示例中,您只是随意更改成员,static或者只是尝试编译.
考虑一下......在static上下文中你根本就没有实例,所以在static构造函数上访问实例成员是不可能的......而且,在调用静态构造函数时,你无法做到有任何初始化的实例,甚至是外部定义的,因为它总是在你有机会初始化之前被调用.
所以静态构造函数中的这一行毫无意义:
c = new Apple(b.getDna());
Run Code Online (Sandbox Code Playgroud)
您正在尝试访问b,这是一个实例成员,但您不是说应该从哪个实例获取值.
你应该重新考虑你的设计,并思考为什么成员会是静态的,而不仅仅是"移动并尝试使其编译和运行".