2011-09-13 43 views
15

tengo una clase repositorio y una Clase de Servicios de la siguiente manera:¿Un inicializador de campo no puede hacer referencia al campo, método o propiedad no estático?

public class DinnerRepository 
{ 
    DinnerDataContext db = new DinnerDataContext(); 

    public Dinner GetDinner(int id) 
    { 
     return db.Dinners.SingleOrDefault(d => d.DinnerID == id); 
    } 

// Others Code   
} 



public class Service 
{ 
     DinnerRepository repo = new DinnerRepository(); 
     Dinner dinner = repo.GetDinner(5); 

// Other Code 
} 

Esto arroja error:

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

Aunque he intatiated la Clase DinnerRepository para exponer su método GetDinner() en el Servicio Clase. Esto funciona bien con el siguiente código. ¿Hay alguna alternativa o es una práctica estándar? No puedo utilizar los métodos estáticos aquí ..

public class Service 
{ 

    public Service() 
    { 
     DinnerRepository repo = new DinnerRepository(); 
     Dinner dinner = repo.GetDinner(5); 
    } 

} 

Respuesta

18

personal que acababa de inicializar los campos de un constructor:

public class Service 
{ 
    private readonly DinnerRepository repo; 
    private readonly Dinner dinner; 

    public Service() 
    { 
     repo = new DinnerRepository(); 
     dinner = repo.GetDinner(5); 
    } 
} 

Tenga en cuenta que esto no es el mismo que el código que muestra en la parte inferior de la pregunta, ya que solo se declaran variables locales. Si solo quiere variables locales, está bien, pero si necesita variables de instancias, utilice el código anterior.

Básicamente, los inicializadores de campo están limitados en lo que pueden hacer. Desde la sección 10.5.5.2 de la C# 4 especificaciones:

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, because it is a compile-time error for a variable initializer to reference any instance member through a simple-name.

(Eso "así" y "por lo tanto" se parece al revés para mí - que es ilegal para hacer referencia a un miembro a través de un simple nombre porque se referencias this - voy a hacer ping Mads sobre ella -. pero eso es básicamente la sección correspondiente)

+0

Sí, la versión actual dice "dado que tenemos un error de tiempo de compilación en' simple-name's, hacemos que la referencia 'this' sea un error", y no al revés. – SWeko

+0

@JonSkeet El motivo de este comportamiento es que los campos se inicializan antes que el constructor. Entonces, no hay ningún miembro de instancia cuando intentas inicializar los campos. Es por eso que no puedes usarlos antes de que la clase sea instanciada ¿Correcto? – UfukSURMEN

+1

@UfukSURMEN: No realmente ... el objeto ya existe, pero invitaría a algunos errores bastante difíciles de razonar. (A veces es muy molesto, de verdad ...) –

2

aunque las manifestaciones initializaton están garantizados para estar en el "textual order", es ilegal que una instancia campos inicializadores to access the this reference, y que son implícitamente usándolo en

Dinner dinner = repo.GetDinner(5); 

lo que equivale a

Dinner dinner = this.repo.GetDinner(5); 

El mejor en mi humilde opinión la práctica, es reservar inicializaciones de campo a valores constantes o para un simple new comunicado. Cualquier cosa más peluda que eso debería ir a un constructor.

Cuestiones relacionadas