2009-09-16 5 views
7

가 정적 뭔가를 찾고 왜 내가 알아낼 수 없습니다 액세스 할 수 없습니다. 나는 데이터베이스 클래스에서 정적 인 것을 볼 수 없다. 왜 그런가?비 정적 필드

여기에 우리가 좀 같은 일을했을 때의 또 다른 예입니다 :

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

또는 ...

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

우리는 정확한 오류 메시지를 제공하기 위해 열심히 일했다 ... 그것으로 작동, 그래서 읽을 면밀히. 오류 메시지는 정확히 무엇이 잘못되고 있는지 알려주고 있습니다. 정적으로 액세스하는 경우에만 컨텍스트에서 비 정적 필드에 액세스하고 있습니다.

왜 기본 생성자 호출 인수 목록은 통계에 액세스하는 경우에만 컨텍스트를 나열합니까?

기본 생성자를 호출 할 때 인수는 "this"을 참조하면 안됩니다. 왜? 파생 생성자도 "this"의 기본 생성자도 아직 실행되지 않았으므로 "this"는 거의 일관성없고 부분 초기화 된 상태입니다. 이것은 미친 버그를 만드는 방법입니다. 따라서 최소한 기본 생성자가 실행될 때까지 "this"에 액세스하지 못하도록 제한합니다.

이 기능은 현명하고, 잘 정돈되고, 이해할 수 있고 유지 보수가 가능하며 버그가없는 건설 논리를 장려합니다. 나는 그 안전 장치와 함께 일하는 것이 좋습니다.

+0

이 특별한 경우에,'connectionString' ** 필드의 * initializer *는 ** 이미 실행됩니다 (이니셜 라이저는 먼저, derived-to-base, ctors, base-to-derived). 기본 ctor의 매개 변수가 초기화됩니다. –

+0

물론이 특별한 경우가 타당했는지, 다른 경우에 대한 다른 행동이 혼란 스럽기 때문에 이것이 왜 특별한 이유가 아닌지 이해합니다. 그러나 이것이 내 [이 질문] (http://stackoverflow.com/q/17342367/11545)에 대한 것이면 나는 확신하지 못한다. 좀 봐 주 시겠어요? –