2009-08-17 36 views
25

Tôi đã đọc một vài bit và bobs trực tuyến về chủ đề này nhưng không tìm thấy nó có tác dụng với tôi. Điều tôi đang cố gắng làm là tạo một lớp Kiểu thời gian chạy.Activator.CreateInstance - Cách tạo ra các thể hiện của các lớp có các hàm tạo tham số

Tôi sử dụng Activator.CreateInstance hoạt động tốt cho các lớp có nhà thầu không chứa đối số. Đối với những người có lý lẽ nó ném một ngoại lệ, là có một cách xung quanh này?

Tôi rất vui khi chuyển giá trị rỗng hoặc giá trị trống cho ctor miễn là tôi có thể tự tạo lớp.

+0

(trả lời bình luận) –

+0

Câu hỏi không phải là một bản sao, nhưng câu trả lời là: http://stackoverflow.com/questions/731452/create-instance-of-generic-type – nawfal

+0

thể trùng lặp của [ Cách chuyển các tham số đến Activator.CreateInstance ()] (http://stackoverflow.com/questions/2451336/how-to-pass-parameters-to-activator-createinstancet) –

Trả lời

7

tôi cuối cùng đã kết thúc làm một cái gì đó như thế này - một số của những người bình luận gợi ý về giải pháp này.

Tôi cơ bản lặp qua tất cả các nhà thầu có sẵn và chọn đơn giản nhất. Sau đó tôi tạo dữ liệu null để vượt qua vào ctor (đối với những gì Im sử dụng nó cho phương pháp này là tốt)

Một phần của mã trông một chút như thế này

// If we have a ctor that requires parameters then pass null values 
if (requiresParameters) 
{ 
    List<object> parameters = new List<object>(); 
    ParameterInfo[] pInfos = constructorInfos[0].GetParameters(); 

    foreach (ParameterInfo pi in pInfos) 
    { 
     parameters.Add(createType(pi.ParameterType)); 
    } 

    return constructorInfos[0].Invoke(parameters.ToArray()); 
} 
+0

'constructorInfos [0] .GetParameters(). Chọn (pi => createType (pi.ParameterType)). ToArray()' – ErikE

46

Có một tình trạng quá tải mà chấp nhận lập luận như một params object[]:

object obj = Activator.CreateInstance(typeof(StringBuilder), "abc"); 

có này làm gì? Thay thế, bạn có thể sử dụng phản ánh để tìm các nhà xây dựng chính xác:

Type[] argTypes = new Type[] {typeof(string)}; 
object[] argValues = new object[] {"abc"}; 
ConstructorInfo ctor = typeof(StringBuilder).GetConstructor(argTypes); 
object obj = ctor.Invoke(argValues); 
+0

Chỉ cần tò mò, điều này sẽ tốt hơn từ quan điểm thực hiện: nhận danh sách các hàm tạo và gọi một hàm tạo cụ thể thông qua sự phản chiếu hoặc gọi trực tiếp Activator.CreateInstance với đối tượng []? –

+1

Tôi mong đợi phương pháp ConstructorInfo. Nếu không, nó phải suy nghĩ về những giá trị nào tương thích với các nhà xây dựng nào - đặc biệt nếu bạn đã vượt qua "null" vv (có thể khớp với nhiều hàm tạo). –

+1

Nhưng bạn có thể thực hiện nó ;-p Trên thực tế, nếu hiệu suất là một cân nhắc quan trọng, bạn có thể xem một biểu thức LINQ được biên dịch trước (vì đây là .NET 3.5) đại diện cho hàm tạo. Hãy cho tôi biết nếu bạn muốn có một ví dụ về điều này. –

0

Activator.CreateInstance cũng có một bó toàn bộ quá tải, một bạn có thể muốn kiểm tra là (Type type, params object [] args). Chỉ cần cung cấp các đối số hàm tạo cần thiết cho tham số thứ hai của cuộc gọi này.

Hãy chắc chắn rằng bạn xử lý ngoại lệ ở đây mặc dù, vì nó rất dễ dàng để vượt qua các thông số không chính xác hoặc một cái gì đó để thay đổi trong constructor của loại sau này mà phá vỡ nó ..

1

Tôi đang sử dụng phương pháp này để có được khoảng an issue I ran into và dường như nó hoạt động đúng như tôi mong đợi. :)

object instance = Activator.CreateInstance(
    typeof(OpCode), 
    BindingFlags.NonPublic | BindingFlags.Instance, 
    default(Binder), 
    new object[] { stringname, pop, push, operand, type, size, s1, s2, ctrl, endsjmpblk, stack }, 
    default(CultureInfo)); 
+0

Có thể được sử dụng trên bất kỳ kiểu...? – Chris

0

Để thay thế cho Activator.CreateInstance, FastObjectFactory trong khuôn phôi url liên kết tốt hơn so với Activator (như của .NET 4.0 và đáng kể hơn so với .NET 3.5. Không kiểm tra/số liệu thống kê thực hiện với .NET 4.5) . Xem bài đăng StackOverflow để biết thống kê, thông tin và mã. Lưu ý rằng một số sửa đổi có thể cần phải được thực hiện dựa trên số lượng tham số ctor. Mã được cung cấp chỉ cho phép 1 tham số ctor nhưng có thể được sửa đổi để có nhiều hơn 1. Xem chú thích trong mã.

How to pass ctor args in Activator.CreateInstance or use IL?

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