2008-10-20 25 views
18

Tôi muốn biết sự khác biệt giữa khởi tạo một thành viên tĩnh inline như trong là gì:Difference khởi inline biến tĩnh hoặc trong constructor tĩnh trong C#

class Foo 
{ 
    private static Bar bar_ = new Bar(); 
} 

hoặc khởi tạo nó bên trong constructor tĩnh như trong:

class Foo 
{ 
    static Foo() 
    { 
     bar_ = new Bar(); 
    } 
    private static Bar bar_; 
} 
+0

check out: http://stackoverflow.com/a/40939743/4038978 –

Trả lời

17

Nếu bạn có một hàm tạo tĩnh trong loại của bạn, nó sẽ thay đổi loại khởi tạo do cờ beforefieldinit không còn được áp dụng nữa.

Nó cũng ảnh hưởng đến thứ tự khởi tạo - biến khởi tạo biến được thực thi trước hàm dựng tĩnh.

Đó là về nó theo như tôi biết.

+3

Ví dụ cụ thể về lý do tại sao lại quan trọng: http://stackoverflow.com/questions/217932/whats-the-difference-in-these-ways-of-creating-the-static-instance-for-a-single # 218005 –

+0

Từ liên kết của bạn: 'Thời gian chạy có thể quyết định chạy trình khởi tạo kiểu khi tải assembly để bắt đầu bằng'. Tôi giả định với các lớp chung chung ('lớp mẫu ') các quy tắc thay đổi? Với độ phân giải thời gian biên dịch (ví dụ: C++) các quy tắc sẽ giống nhau, nhưng .NET có độ phân giải thời gian chạy. Thời gian chạy sẽ không được instantiating cho mọi kết hợp có thể, và tôi nghi ngờ rằng trên tải lắp ráp nó sẽ nhìn về phía trước để xem những loại được sử dụng. –

+0

@NelsonRothermel: Nó khởi tạo kiểu lần đầu tiên xây dựng kiểu được sử dụng - vì vậy nếu bạn sử dụng 'Foo ' nó sẽ khởi tạo sau đó, và sau đó chạy trình khởi tạo kiểu nếu bạn sử dụng 'Foo '. –

3

Trong trường hợp này, tôi không tin rằng có bất kỳ sự khác biệt thực tế nào. Nếu bạn cần một số logic trong việc khởi tạo các biến tĩnh - giống như nếu bạn muốn sử dụng các loại bê tông khác nhau của một giao diện cho các điều kiện khác nhau - bạn sẽ sử dụng hàm tạo tĩnh. Khác, khởi tạo nội tuyến là tốt trong cuốn sách của tôi.

class Foo 
{ 
    private static IBar _bar; 

    static Foo() 
    { 
     if(something) 
     { 
      _bar = new BarA(); 
     } 
     else 
     { 
      _bar = new BarB(); 
     } 
    } 
} 
+0

Trên thực tế, nó có thể làm cho một thực tế lớn sự khác biệt - xem ở đây (sự khác biệt là "công trình" so với "không"): http://stackoverflow.com/questions/217932/whats-the-difference-in-these-ways-of-creating-the-static -instance-for-a-single # 218005 –

+0

Tôi tìm thấy địa điểm ion mô tả ở đó rất lạ: | Suy nghĩ về điều đó, trong những người độc thân của tôi, tôi luôn sử dụng hai đối tượng tĩnh, ví dụ thực tế và một đối tượng để khóa. Ví dụ tôi luôn tạo trong một phương thức thuộc tính, đối tượng khóa mà tôi khởi tạo nội tuyến. Tôi chưa bao giờ nghĩ về nó trước đây. –

+0

Tobjorn: Điều đó nghe có vẻ như bạn thường đang khóa khi bạn không cần phải :) (Hầu hết thời gian tôi thấy rằng các đảm bảo khởi tạo tĩnh là hoàn toàn phù hợp cho người độc thân.) –

-1

Câu trả lời vùng hoàng hôn: Có sự khác biệt trong thứ tự thực hiện giữa khởi tạo nội tuyến và gán ctor ... khi bạn kết hợp các thành viên ví dụ và tĩnh và kế thừa để khởi động.

For static members, static initializers 
Static ctors (execute bottom up) 
Base static initializer 
Base static ctor and so on 

For instance members, initializers in current class execute first 
Then initializers in base class execute (up the chain) 
Then top-most base ctor is executed (and we walk down now. Instance ctors execute top-down) 
Finally current type's ctor is executed. 

Ví dụ :)

public class CBase 
    { 
     static Talkative m_Baseob1 = new Talkative("Base Static Initializer-"); 
     static Talkative m_Baseob2; 
     Talkative m_Baseob3 = new Talkative("Base Inst Initializer"); 
     Talkative m_Baseob4; 
     static CBase() 
     { 
      Console.WriteLine("***MethodBegin: Static Base Ctor"); 
      m_Baseob2 = new Talkative("Base Static Ctor"); 
      Console.WriteLine("***MethodEnd: Static Base Ctor"); 
     } 
     public CBase() 
     { 
      Console.WriteLine("***MethodBegin: Instance Base Ctor"); 
      m_Baseob4 = new Talkative("Base Instance Ctor"); 
      Console.WriteLine("***MethodEnd: Instance Base Ctor"); 
     } 
    } 
    public class CDerived : CBase 
    { 
     static Talkative m_ob1 = new Talkative("Derived Static Initializer"); 
     static Talkative m_ob2; 
     Talkative m_ob3 = new Talkative("Derived Inst Initializer"); 
     Talkative m_ob4; 
     static CDerived() 
     { 
      Console.WriteLine("***MethodBegin: Derived Static Ctor"); 
      m_ob2 = new Talkative("Derived Static Ctor"); 
      Console.WriteLine("***MethodEnd: Derived Static Ctor"); 
     } 
     public CDerived() 
     { 
      Console.WriteLine("***MethodBegin: Derived Instance Ctor"); 
      m_ob4 = new Talkative("Derived Instance Ctor"); 
      Console.WriteLine("***MethodEnd: Derived Instance Ctor"); 
     } 
    } 
    internal class Talkative 
    { 
     public Talkative(string sID) 
     { 
      Console.WriteLine(sID + " - Talkative created"); 
     } 
    } 

    # Main function somewhere 
    CDerived s = new CDerived(); 

Output:

Derived Static Initializer - Talkative created 

***MethodBegin: Derived Static Ctor 
Derived Static Ctor - Talkative created 
***MethodEnd: Derived Static Ctor 

Derived Inst Initializer - Talkative created 

Base Static Initializer- - Talkative created 

***MethodBegin: Static Base Ctor 
Base Static Ctor - Talkative created 
***MethodEnd: Static Base Ctor 

Base Inst Initializer - Talkative created 

***MethodBegin: Instance Base Ctor 
Base Instance Ctor - Talkative created 
***MethodEnd: Instance Base Ctor 

***MethodBegin: Derived Instance Ctor 
Derived Instance Ctor - Talkative created 
***MethodEnd: Derived Instance Ctor 
+0

Ở đây, hàm tạo static của CBase chỉ được gọi vì một cá thể của CDerived đang được xây dựng. Nếu bạn chỉ cần gọi một phương thức trong CDerived mà không cần phải chạm vào CBase, thì hàm tạo static của CBase sẽ không được gọi. –

+0

Tôi sẽ ngạc nhiên nếu nó đã làm .. Tôi đã đề cập đến thừa kế trong câu đầu tiên. Điểm của tôi: Sự khác biệt trong cách một biến được khởi tạo dựa trên cách (khởi tạo trường hoặc trong ctor), cho dù tĩnh/inst và cho dù đó là trong một hệ thống phân cấp loại. nhưng yeah .. Ans của tôi là kinda overkill cho q của OP;) – Gishu