2009-09-16 4 views
7

я не могу понять, почему он ищет нечто статичное:не удается получить доступ к нестатическая поле

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

я не удается получить доступ к нестатический поле «ConnectionString» в статическом контексте. Я не вижу ничего статического в базовом классе базы данных, так почему?

вот еще один пример, когда мы сделали любопытные то же самое:

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

ИТАК, почему это должно быть статичной строкой для строки соединения будет принято?

ответ

4

Ваша проблема в конструкторе MyDB. Поле экземпляра (MyDB.connectionString) не будет инициализировано до тех пор, пока вызов базового конструктора не вернется, поэтому все внутри base(...) находится в статическом контексте. Просто работать с ним ...

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

или еще лучше (как это было предложено Simon Fox) ...

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

Итак, как я могу отправить эту строку соединения в базовый конструктор по мере необходимости? – PositiveGuy

+3

Ваши решения в порядке, но ваш анализ полностью неверен *. Поле intstance будет инициализировано до вызова базового конструктора. Порядок построения: инициализаторы производных полей, инициализаторы базового поля, тело базового конструктора, производное тело конструктора. –

+1

См. Мои статьи по этому вопросу, почему заказ выполняется именно так: http://blogs.msdn.com/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order -as-constructors-part-one.aspx и http://blogs.msdn.com/ericlippert/archive/2008/02/18/why-do-initializers-run-in-the-opposite-order-as-constructors -part-two.aspx –

26

Мы упорно трудились, чтобы дать сообщения об ошибках, которые являются точными, так что читать их внимательно. Сообщение об ошибке сообщает вам, что именно происходит: вы получаете доступ к нестатическому полю в контексте, где для доступа к статистике только законно.

Итак, почему в списке аргументов вызова конструктора базы есть контекст, в котором разрешено только доступ к статистике?

Когда вы вызываете базовый конструктор, аргументы, которые вы передаете , не должны ссылаться на «это». Зачем? Потому что ни производный конструктор, ни базовый конструктор для вашего «этого» еще не запущены, и поэтому «это» почти наверняка находится в несогласованном, частично инициализированном состоянии. Это рецепт сумасшедших ошибок. Поэтому мы ограничиваем доступ к «этому» до тех пор, пока не узнаем, что, по крайней мере, работает базовый конструктор.

Эта функция поощряет разумную, упорядоченную, понятную, поддерживаемую и не требующую ошибок конструкцию логики; Я рекомендую работать с этими гарантиями, а не против них.

+0

В этом конкретном случае * инициализатор * для поля 'connectionString' ** ** уже запущен (инициализаторы сначала, производные от базы, затем ctors, base-to-производные), поэтому инициализируется параметр базы ctor. –

+0

Конечно, если бы этот конкретный случай был действительным, разные формы поведения для разных случаев были бы путаными, поэтому я понимаю, почему это не было специально. Но я не уверен, что это относится к [этому моему вопросу] (http://stackoverflow.com/q/17342367/11545), комментарий которого привел меня сюда. Не могли бы вы взглянуть? –

Смежные вопросы