8

In code below I must declare method MdrResponseInterpreter static otherwise I have compilation error.

class.... {

    private StandardBuilder _mdrResponseBuilder = 
      new StandardBuilder(MdrResponseInterpreter);

    public static bool MdrResponseInterpreter(DNMessageDeliverer builder, 
                                              DNFieldSet message)
    {
        // .... work
    }

Why? As _mdrResponseBuilder is not static I expect that MdrResponseInterpreter should be able to access this

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305

4 Answers4

11

Because field initializers don't have access to this / instance members. Move the initialization to the constructor if you want access to instance members.

The spec says:

A variable initializer for an instance field cannot reference the instance being created. Thus, it is a compile-time error to reference this in a variable initializer

While your code doesn't explicitly reference this, the method group to delegate conversion does reference this implicitly if the method is an instance member.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
5

To add to CodeInChaos's answer (which is correct) you can just move the assignment to the constructor:

private StandartBuilder _mdrResponsBuilder;

public Foo() // Whatever your type is called
{
    // Simpler syntax for creating a delegate, too. Just use a
    // method group conversion...
    _mdrResponsBuilder = MdrResponseInterpreter;
}

EDIT: The above assumes that StandartBuilder is a delegate type. If it's a type with a constructor accepting a delegate type, then you'll need to go back to new StandartBuilder(MdrResponseInterpreter), but still have it in the constructor.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Just wondering, how is that "_mdrResponsBuilder = MdrResponseInterpreter" is correct? Nothing in the question indicates that StandardBuilder is a delegate... It could be a class accepting a Func in its constructor? Btw, I didn't downvote – odalet Mar 28 '12 at 09:56
  • 1
    @odalet: Yes, that's possible. I think it's more likely (given the question title) that it's a delegate type. Will edit to clarify. – Jon Skeet Mar 28 '12 at 09:58
1

You are not allowed to use instance members in initializers.

Think of a delegate as having 1) An object reference and 2) A method reference. Since you cannot access this, there is no way to set the object reference, so the only way to be able to use the method as a delegate is to declare it as static (because a delegate's object reference is null for static methods). Moving your initialization to the constructor can help you get around this.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • 1
    There definitely *is* an object at that point (otherwise where is the value being assigned?) but you're not allowed to access `this` yet. – Jon Skeet Mar 28 '12 at 09:21
  • I'd still say it's unclear. The object *does* exist, fully. It may not have been fully *initialized*, but that's true in the constructor body too. (There may be other derived constructor bodies which have yet to run, too...) – Jon Skeet Mar 28 '12 at 09:25
1

The method has to be static because it is invoked at object initialization, before the constructor has started executing. If you want to access this, call the initialization method from inside your constructor.

Marnix van Valen
  • 13,265
  • 4
  • 47
  • 74