2010-03-26 24 views
12

Làm cách nào để có được ConstructorInfo cho một hàm tạo tĩnh?Làm cách nào để gọi một hàm tạo tĩnh có phản ánh?

public class MyClass 
{ 
    public static int SomeValue; 

    static MyClass() 
    { 
     SomeValue = 23; 
    } 
} 

Tôi đã thử những điều sau đây và thất bại ....

Type myClass = typeof (MyClass); 

// throws exception 
myClass.TypeInitializer.Invoke(null);  

// returns null (also tried deleting BindingFlags.Public 
ConstructorInfo ci = myClass.GetConstructor(BindingFlags.Static|BindingFlags.Public, System.Type.DefaultBinder, System.Type.EmptyTypes, null); 

// returns empty array 
ConstructorInfo[] clutchingAtStraws = myClass.GetConstructors(BindingFlags.Static| BindingFlags.Public); 

Trả lời

27

Sử dụng myClass.TypeInitializer.Invoke(null, null).

Tôi vừa thử cách này và hoạt động tốt.

Tôi thực sự khuyên bạn không nên không làm điều này, tuy nhiên - vi phạm loại mong đợi hàm tạo tĩnh chỉ được thực hiện một lần. Sử dụng RuntimeHelpers.RunClassConstructor theo Oliver's answer nếu bạn chỉ đang cố gắng đảm bảo một lớp học được khởi tạo.

+0

+1 nhờ Jon! Câu trả lời dường như rất rõ ràng bây giờ * grin * –

+0

Tôi cần truy cập nó theo thứ tự [để áp dụng một khía cạnh cho nó bằng cách sử dụng PostSharp] (http://www.sharpcrafters.com/). Tôi đoán rằng vẫn là một trường hợp sử dụng hợp lệ. –

+2

Bị bỏ phiếu, chỉ vì câu trả lời tiếp theo là (ít nhất là về lý thuyết) an toàn hơn nhiều. p.s. ... Chết tiệt, tôi vừa mới trả lời câu trả lời của Jon Skeet. Tôi không đậm? –

2

Bạn cũng đã thử BindingFlags.Private? Lưu ý, rằng hàm tạo tĩnh được đảm bảo là get được gọi trước khi bất kỳ cuộc gọi nào khác hoặc các phương thức tĩnh của lớp này, và nó được đảm bảo là luồng an toàn và được gọi chính xác một lần.

Nếu bạn rõ ràng sẽ gọi nó với suy nghĩ bạn có thể làm rất nhiều tác hại ..

7

Mặc dù nó là có thể, nó có thể không phải là một ý tưởng tốt để làm điều đó. Tuy nhiên, nếu bạn truy cập bất kỳ thành viên nào của lớp, thời gian chạy sẽ tự động gọi hàm tạo tĩnh cho bạn. Ví dụ:

// Read the field 'SomeValue', so that the runtime invokes static ctor 
Type myClass = typeof(MyClass); 
myClass.GetField("SomeValue").GetValue(null); 

Kể từ khi truy cập vào một lĩnh vực của lớp không thể gây ra bất kỳ tác dụng phụ (trừ khởi của lớp và gọi đến constructor tĩnh), điều này sẽ là một cách tương đối an toàn để thực hiện điều này nói chung (Tuy nhiên, nó sẽ stil làm việc chỉ cho các lớp học với một số lĩnh vực tĩnh). Điều này có lợi ích là nó đảm bảo rằng hàm tạo kiểu sẽ được gọi tối đa một lần là, điều này khá quan trọng.

+1

Lạ lùng, nhưng tôi đã đến câu hỏi này chỉ vì lĩnh vực chỉ đọc mà tôi cần không được bắt đầu vào thời điểm tôi truy cập nó. Tôi có thể đặt cược, hầu hết mọi người đều ở đây vì lý do rất giống nhau. –

23

Ngoài ra còn có System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle type) định bổ sung đảm bảo rằng các nhà xây dựng tĩnh chỉ được gọi một lần, bất kể bao nhiêu lần phương pháp này được gọi là:

Type myClass = typeof(MyClass); 
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(myClass.TypeHandle); 

Reference

+5

Đây là câu trả lời đúng thực tế. Điều đó đã cứu mạng tôi khỏi cái chết nhất định !!!! – Xtro

Các vấn đề liên quan