如何使用属性初始化另一个属性?

时间:2016-06-16 11:54:58

标签: c# constructor properties roslyn c#-6.0

为什么:

public int X { get; } = 5
public int Y { get; } = X;

不可能?

因为手动操作:

public TestClass()
{
  X = 5;
  Y = X;
}

工作,(显然?)这样做:

public static int X { get; } = 5;
public static int Y { get; } = X;

有没有办法让第一个例子编译,还是我必须在ctor中手动完成?

(我真正的问题要复杂得多,不仅仅是整数,而是用于创建其他实例的实例,但这个例子更容易讨论)

2 个答案:

答案 0 :(得分:5)

这是不可能的原因是这些初始化是在调用构造函数之前完成的。所以它发生在静态上下文中。该对象尚未完全初始化,尚未有this引用。因此,您无法访问非静态属性,例如X

出于同样的原因,它适用于第三个示例中的 static 属性。

所以我没有看到解决方法,而是在构造函数中进行这种初始化。

答案 1 :(得分:2)

您不能在属性X的初始化表达式中使用非静态属性Y的值,原因与您无法使用非静态字段{{1}的值的原因相同在字段x的初始化表达式中,即

y

这会触发error CS0236,因为允许编译器决定它处理部分类的字段和属性初始值设定项的顺序。虽然public int x = 5; public int y = x; // Not allowed 保证在X之前在同一文件中定义两个属性时进行初始化,但对于包含部分类代码的不同文件中定义的属性没有这样的保证。

编译器设计人员可以通过允许初始化器引用在字段或属性初始化之前定义的其他字段和属性来实现它,但是该功能不值得麻烦,因为您可以通过将初始化移动到构造函数中来轻松解决它。

在构造函数中执行相同操作不会出现问题,因为您可以控制赋值的顺序。当您在构造函数中说Y必须在X之前初始化时,不允许编译器更改该顺序。