Auto property with initializer referencing instance member

This is working code

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) { ... }
}

And this one is not

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) { ... }
}

Error is

Error CS0236 A field initializer cannot reference the non-static field, method, or property

My question is: why? Why should something be static? This is supposed to be a cool feature.

Jon Skeet
people
quotationmark

There's nothing new here, really. Forget automatically implemented properties - you simply can't refer to this within a field initializer. (Let's face it, you're trying to initialize a field under the hood - just a field which is only exposed via a property.)

So this has always been invalid:

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

    int DoSomething() { ... }
}

Generally, this avoids:

  • Reliance on initialization order, which can lead to brittle code
  • Calling methods before the base class initializer has executed

I agree that for method group conversions it's a bit of an unnecessary pain - but the language is simpler with just one rule.

As you've seen, you can easily put the code in the constructor - so I'd just go with that. (And hey, at least we do now have read-only automatically-implemented properties that can be initialized from constructors...)

It's important to understand that the compiler error message isn't really telling you that anything should be static - it's just telling you what you can't do. The solution depends on your situation - and in this case, the right solution is almost certainly to put the initialization in a constructor.

people

See more on this question at Stackoverflow