2009-09-16 14 views
7

ich kann nicht herausfinden, warum es für etwas Statisches suchen ist:Keinen Zugriff auf nicht-statisches Feld

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) 
    {   
    } 
} 

ich zugreifen kann nicht nicht-statisches Feld ‚Connection‘ in statischem Kontext erhalten. Ich sehe nichts statisches in der Basis-Datenbank-Klasse, also warum?

hier ist ein weiteres Beispiel dafür, wann wir haben irgendwie das Gleiche:

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

ok so, warum hat es eine statische Zeichenfolge für die Verbindungszeichenfolge sein müssen weitergegeben werden?

Antwort

4

Ihr Problem liegt im MyDB-Konstruktor. Das Instanzfeld (MyDB.connectionString) wird nicht initialisiert, bis der Aufruf des Basiskonstruktors zurückkehrt, sodass sich alles innerhalb von base(...) im statischen Kontext befindet. einfach damit arbeiten ...

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

oder besser noch (wie von Simon Fox vorgeschlagen) ...

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

also wie kann ich diese Verbindungszeichenfolge an den Basiskonstruktor wie erforderlich senden? – PositiveGuy

+3

Ihre Lösungen sind in Ordnung, aber Ihre Analyse ist * völlig inkorrekt *. Das Intstance-Feld wird initialisiert, bevor der Basiskonstruktor aufgerufen wird. Die Reihenfolge der Konstruktion lautet: abgeleitete Feldinitialisierer, Basisfeldinitialisierer, Basiskonstruktorkörper, abgeleiteter Konstruktorkörper. –

+1

Siehe meine Artikel zu diesem Thema für warum die Bestellung so ist: http://blogs.msdn.com/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order -as-constructors-part-one.aspx und http://blogs.msdn.com/ericlippert/archive/2008/02/18/why-do-initializers-run-in-the-opposite-order-as-constructors -part-two.aspx –

26

Wir haben hart gearbeitet Fehlermeldungen zu geben, die genau sind, so lesen sie vorsichtig. Die Fehlermeldung sagt Ihnen genau, was schief läuft: Sie greifen auf ein nicht statisches Feld in einem Kontext zu, in dem es nur legal ist, auf Statik zuzugreifen.

Also warum ist ein Basiskonstruktor Aufruf Argument Liste einen Kontext, in dem es nur legal ist, auf Statik zuzugreifen?

Wenn Sie einen Basiskonstruktor aufrufen, dürfen die übergebenen Argumente nicht "this" verweisen. Warum? Da weder der abgeleitete Konstruktor noch der Basiskonstruktor für Ihr "Dies" bereits ausgeführt wurde, ist "dieses" höchstwahrscheinlich in einem inkonsistenten, teilweise initialisierten Zustand. Das ist ein Rezept für verrückte Bugs. Wir beschränken daher den Zugriff auf "dieses", bis wir wissen, dass zumindest der Basiskonstruktor ausgeführt wurde.

Diese Funktion unterstützt eine vernünftige, gut geordnete, verständliche, wartbare und fehlerfreie Konstruktionslogik. Ich empfehle, mit diesen Sicherheitsvorkehrungen zu arbeiten, nicht dagegen.

+0

In diesem speziellen Fall hat der * Initialisierer * für das Feld 'connectionString' ** ** bereits ausgeführt (Initialisierer zuerst, abgeleitete-zu-Basis, dann ctors, Basis-zu-abgeleitet), also Der Parameter für den Basis-Ctor wird initialisiert. –

+0

Natürlich, wenn dieser spezielle Fall gültig wäre, wären die unterschiedlichen Verhaltensweisen für die verschiedenen Fälle verwirrend, also verstehe ich, warum dies nicht speziell war. Aber ich bin mir nicht sicher, ob das für [meine Frage] gilt (http://stackoverflow.com/q/17342367/11545), ein Kommentar, der mich hierher geführt hat. Könnten Sie einen Blick darauf werfen? –

Verwandte Themen