¿Por qué no puedes usar ‘esto’ en los inicializadores de miembros?

Posible duplicado:
¿No se puede usar ‘this’ en el inicializador de miembros?

Cualquier idea de por qué recibo un error si bash hacer algo como esto:

public class Bar { public Bar(Foo foo) { } } public class Foo { private Bar _bar = new Bar(this); } 

Me sale un error diciendo:

“No se puede usar ‘esto’ en el inicializador de miembros”

Pero las siguientes obras:

 public class Foo { private Bar _bar; public Foo() { _bar = new Bar(this); } } 

Alguien sabe la razón detrás de esto? Mi entendimiento fue que estos se comstackrían en la misma IL, así que tengo curiosidad por saber por qué se permite una y la otra no.

Gracias alex

Sospecho que es para evitar que uses el objeto antes de que al menos el constructor de la clase base se haya ejecutado, asegurándome de que todos los miembros de la clase base estén inicializados apropiadamente. (Los inicializadores de variables se ejecutan antes que el constructor de la clase base, mientras que el cuerpo del constructor se ejecuta después de eso).

Comprobaré si la especificación anotada tiene algo que decir al respecto cuando esté cerca …

EDITAR: La especificación anotada C # 4 no tiene ninguna explicación. Solo (en 10.5.5.2):

Un inicializador de variable para un campo de instancia no puede hacer referencia a la instancia que se está creando.

Los inicializadores de campo se ejecutan antes que los constructores de la clase base, por this que aún no existe. Solo existe una vez que el constructor base ha terminado de ejecutarse.

17.10.2 Inicializadores de variables de instancia :

Cuando un constructor de instancia no tiene un inicializador de constructor, o tiene un inicializador de constructor de la base de formulario (…), ese constructor realiza implícitamente las inicializaciones especificadas por los inicializadores de variables de los campos de instancia declarados en su clase. Esto corresponde a una secuencia de asignaciones que se ejecutan inmediatamente después de la entrada al constructor y antes de la invocación implícita del constructor directo de la clase base. Los inicializadores variables se ejecutan en el orden textual en el que aparecen en la statement de clase.

Creo que esto se debe a que los campos se inicializan antes de que la clase se inicialice, de modo que cuando se ejecuta el siguiente código:

 private Bar _bar = new Bar(this); 

“esto” no tiene un valor real al que hacer referencia.

Mientras que ponerlo en el constructor significa que hay una instancia de “Foo” referencable por “esto”

Los inicializadores de miembros se ejecutan antes que el constructor de clase. Tenga en cuenta que puede tener muchos inicializadores de miembro en una sola clase.

Si usa ‘this’ en el constructor -> todos los miembros con inicializadores fueron inicializados. Así que todo está bien.

Si usa ‘this’ en el inicializador de miembros: es posible que otros miembros (con los inicializadores adjuntos) aún no se hayan inicializado -> ‘this’ aún no está listo. Es por eso que no está permitido el uso de ‘esto’ aquí no está permitido.

En C #, no se pretende que la lógica esté fuera de los cuerpos de los métodos y propiedades.

Los inicializadores de campo son una excepción, pero con algunas limitaciones.

Sería incorrecto obtener una referencia del objeto actual con esta palabra clave porque una statement de campo de clase no es lógica sino diseño de clase, mientras que esto es parte de la semántica del tiempo de ejecución.

Por cierto, parece que es una decisión de diseño de C #, porque, de hecho, un inicializador de campo se ejecuta durante la construcción de la clase, por lo que la “instancia actual de la clase declarante” debería estar disponible a través de esto . Pero, de nuevo, ¿qué sería esto fuera del scope de un método o cuerpo de propiedad?

Como señalaron Jon Skeet y otros, esto no está disponible porque los inicializadores de campo se ejecutan después de la ejecución del constructor base.