2012-03-28 47 views
8

En el siguiente código debo declarar el método MdrResponseInterpreterstatic de lo contrario tendré un error de compilación.¿por qué el delegado debe ser estático?

class.... { 

    private StandardBuilder _mdrResponseBuilder = 
     new StandardBuilder(MdrResponseInterpreter); 

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

¿Por qué? Como _mdrResponseBuilder no es estática espero que MdrResponseInterpreter debe ser capaz de acceder this

Respuesta

11

Debido inicializadores de campo no tienen acceso a los miembros this/instancia. Mueva la inicialización al constructor si desea acceder a los miembros de la instancia.

La especificación dice:

Un inicializador de variable para un campo de instancia no se puede hacer referencia a la instancia que se crea. Por lo tanto, se trata de un error en tiempo de compilación para hacer referencia this en un inicializador de variable de

Mientras que su código no explícitamente referencia this, el grupo método para delegar conversión no this referencia implícita si el método es un miembro de instancia.

1

No tiene permitido utilizar miembros de instancias en los inicializadores.

Considere que un delegado tiene 1) Una referencia de objeto y 2) Una referencia de método. Como no puede acceder al this, no hay forma de establecer la referencia del objeto, por lo que la única forma de poder usar el método como delegado es declararlo como static (porque la referencia de objeto de un delegado es null para métodos estáticos). Mover su inicialización al constructor puede ayudarlo a evitar esto.

+1

Definitivamente * es * un objeto en ese punto (de lo contrario, ¿dónde se asigna el valor?) Pero aún no tiene permiso para acceder a 'this'. –

+0

Claro, no estaba claro. Actualizado mi respuesta. – Botz3000

+0

Aún diría que no está claro. El objeto * does * existe, completamente. Es posible que no se haya inicializado * por completo, pero eso también es cierto en el cuerpo del constructor. (Puede haber otros cuerpos constructors derivados que aún no se han ejecutado, también ...) –

1

El método tiene que ser estático porque se invoca en la inicialización del objeto, antes de que el constructor haya comenzado a ejecutarse. Si desea acceder al this, llame al método de inicialización desde el interior de su constructor.

5

Para añadir a la respuesta de CodeInChaos (lo cual es correcto) sólo puede mover la asignación al 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: Lo anterior supone que StandartBuilder es un tipo de delegado. Si se trata de un tipo con un constructor que acepta un tipo de delegado, tendrá que volver al new StandartBuilder(MdrResponseInterpreter), pero aún tenerlo en el constructor.

+0

@Downvoter: ¿te gustaría comentar? –

+0

Solo me pregunto, ¿cómo es que "_mdrResponsBuilder = MdrResponseInterpreter" es correcto? Nada en la pregunta indica que StandardBuilder es un delegado ... ¿Podría ser una clase que acepta un Func en su constructor? Por cierto, no devolvió – odalet

+1

@odalet: Sí, eso es posible. Creo que es más probable (dado el título de la pregunta) que sea un tipo de delegado. Editará para aclarar. –

Cuestiones relacionadas