почему делегат должен быть статичным? - PullRequest
8 голосов
/ 28 марта 2012

В приведенном ниже коде я должен объявить метод MdrResponseInterpreter static, иначе у меня будет ошибка компиляции.

class.... {

    private StandardBuilder _mdrResponseBuilder = 
      new StandardBuilder(MdrResponseInterpreter);

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

Почему? Поскольку _mdrResponseBuilder не является статичным, я ожидаю, что MdrResponseInterpreter должен иметь доступ к this

Ответы [ 4 ]

11 голосов
/ 28 марта 2012

Поскольку инициализаторы полей не имеют доступа к this / членам экземпляра.Переместите инициализацию в конструктор, если вам нужен доступ к членам экземпляра.

В спецификации сказано:

Инициализатор переменной для поля экземпляра не может ссылаться на создаваемый экземпляр.Таким образом, ошибка времени компиляции для ссылки this в инициализаторе переменной

Хотя ваш код явно не ссылается на this, группа методов для делегирования преобразования делает ссылку thisнеявно, если метод является членом экземпляра.

5 голосов
/ 28 марта 2012

Чтобы добавить к ответу CodeInChaos (что правильно), вы можете просто переместить присвоение в конструктор:

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;
}

РЕДАКТИРОВАТЬ: Выше предполагается, что StandartBuilder является типом делегата. Если это тип с конструктором , принимающим тип делегата, то вам нужно вернуться к new StandartBuilder(MdrResponseInterpreter), но все же иметь его в конструкторе.

1 голос
/ 28 марта 2012

Метод должен быть статическим, потому что он вызывается при инициализации объекта до начала выполнения конструктора.Если вы хотите получить доступ к this, вызовите метод инициализации из вашего конструктора.

1 голос
/ 28 марта 2012

Вы не можете использовать элементы экземпляра в инициализаторах.

Представьте, что делегат имеет 1) ссылку на объект и 2) ссылку на метод.Поскольку вы не можете получить доступ к this, нет способа установить ссылку на объект, поэтому единственный способ использовать метод в качестве делегата - это объявить его как static (потому что ссылка на объект делегата nullдля статических методов).Перемещение инициализации в конструктор может помочь вам обойти это.

...