具有初始化程序引用实例成员

时间:2015-08-06 12:34:20

标签: c# properties initializer c#-6.0

这是正常工作的代码

public class SomeViewModel
{
    public DelegateCommand CommandA { get; }
    public DelegateCommand CommandB { get; }

    public bool SomeProperty { get; set; }        

    // stupid constructor
    public SomeViewModel()
    {
        CommandA = new DelegateCommand(OnCommandA);
        CommandB = new DelegateCommand(o => SomeProperty = true;);
    }
    void OnCommandA(object obj) { ... }
}

这个不是

public class SomeViewModel
{
    public DelegateCommand CommandA { get; } = new DelegateCommand(OnCommandA); // error
    public DelegateCommand CommandB { get; } = new DelegateCommand(o => SomeProperty = true;); // error

    public bool SomeProperty { get; set; }        

    void OnCommandA(object obj) { ... }
}

错误是

  

错误CS0236字段初始值设定项无法引用非静态字段,方法或属性

我的问题是:为什么?为什么要static?这应该是一个很酷的功能。

1 个答案:

答案 0 :(得分:9)

这里没什么新鲜的,真的。忘记自动实现的属性 - 您根本无法在字段初始值设定项中引用this。 (让我们面对现实吧,你试图在引擎盖下初始化一个字段 - 只是一个只通过属性公开的字段。)

所以这一直都是无效的:

class Foo
{
    int x = 10;
    int y = x; // Nope, compile-time error
    int z = DoSomething(); // Nope...

    int DoSomething() { ... }
}

通常,这可以避免:

  • 依赖于初始化顺序,这会导致代码脆弱
  • 在基类初始化程序执行之前调用方法

我同意对于方法组转换,它是一个不必要的痛苦的 - 但只用一条规则语言就更简单了。

正如您所见,您可以轻松地将代码放在构造函数中 - 所以我只是顺其自然。 (嘿,至少我们现在拥有只读自动实现的属性,可以从构造函数初始化......)

重要的是要理解编译器错误消息并没有真正告诉你任何 应该是静态的 - 它只是告诉你你不能做什么。解决方案取决于您的情况 - 在这种情况下,正确的解决方案几乎肯定是将初始化放在构造函数中。