2009-09-16 23 views
7

No puedo entender por qué se está buscando algo estático:No se puede acceder campo no estático

public class DatabaseBase 
{ 
    private readonly string connectionString; 

    public DatabaseBase(string connectionString) 
    { 
     this.connectionString = connectionString; 
    } 
} 

public class MyDB : DatabaseBase 
{ 
    readonly string connectionString = ConfigurationManager.AppSettings["MyConnectionString"]; 

    public MyDB() : base(connectionString) 
    {   
    } 
} 

consigo No se puede acceder campo no estático 'connectionString' en el contexto estático. No veo nada estático en la clase base de la base de datos, ¿por qué?

aquí es otro ejemplo de cuando hicimos un poco lo mismo:

partial class Database : DatabaseBase 
{ 
    static string DbConnectionString 
    { 
     get 
     { 
      if (dbConnectionString == null) 
       dbConnectionString = 
        ConfigurationManager.AppSettings["MyConnectionString"]; 
      return dbConnectionString; 
     } 
    } 
    public Database() :base(DbConnectionString) 
    { 
    } 

bien así que ¿por qué tiene que ser una cadena estática para la cadena de conexión que pasar?

Respuesta

4

Su problema está en el constructor de MyDB. El campo de instancia (MyDB.connectionString) no se inicializará hasta que vuelva la llamada al constructor base, por lo que todo dentro de base(...) se encuentra en el contexto estático. acaba de trabajar con él ...

public class MyDB : DatabaseBase 
{ 
    static readonly string connectionString = 
      ConfigurationManager.AppSettings["MyConnectionString"]; 
    public MyDB() : base(connectionString) 
    { 
    } 
} 

o mejor aún (según lo sugerido por Simon Fox) ...

public class MyDB : DatabaseBase 
{ 
    public MyDB() : base(ConfigurationManager.AppSettings["MyConnectionString"]) 
    { 
    } 
} 
+0

entonces, ¿cómo puedo enviar esa cadena de conexión al constructor base según sea necesario? – PositiveGuy

+3

Sus soluciones están bien, pero su análisis es * completamente incorrecto *. El campo de entrada se inicializará antes de llamar al constructor base. El orden de construcción es: inicializadores de campo derivados, inicializadores de campo base, cuerpo constructor base, cuerpo constructor derivado. –

+1

Vea mis artículos sobre este tema para saber por qué el orden es así: http://blogs.msdn.com/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order -as-constructors-part-one.aspx y http://blogs.msdn.com/ericlippert/archive/2008/02/18/why-do-initializers-run-in-the-opposite-order-as-constructors -part-two.aspx –

26

Hemos trabajado mucho para dar mensajes de error que son precisas, por lo que los leen cuidadosamente. El mensaje de error le dice exactamente qué está fallando: está accediendo a un campo no estático en un contexto donde es legal acceder a estadísticas.

Entonces, ¿por qué un argumento de llamada al constructor base lista un contexto donde es legal acceder a estáticas?

Cuando llame a un constructor base, los argumentos que pase no deben hacer referencia a "esto". ¿Por qué? Debido a que ni el constructor derivado ni el constructor base para su "esto" se han ejecutado todavía, y por lo tanto, "esto" está casi seguro en un estado incoherente parcialmente inicializado. Esa es una receta para errores locos. Por lo tanto, le restringimos el acceso a "esto" hasta que sepamos que, como mínimo, se ha ejecutado el constructor base.

Esta característica fomenta una lógica de construcción sensata, bien ordenada, comprensible, fácil de mantener y sin errores; Recomiendo trabajar con, y no en contra de, esas salvaguardas.

+0

En este caso particular, el * inicializador * para el campo 'connectionString' ** ya se ha ejecutado ** (inicializadores primero, derivado-a-base, luego ctors, base-a-derivado), entonces el parámetro para el ctor base se inicializa. –

+0

Por supuesto, si este caso particular fuera válido, los diferentes comportamientos para los diferentes casos serían confusos, entonces entiendo por qué esto no fue especial. Pero no estoy seguro de si esto es válido para [esta pregunta mía] (http://stackoverflow.com/q/17342367/11545), un comentario que me ha llevado hasta aquí. ¿Podrías echar un vistazo? –

Cuestiones relacionadas