2010-11-02 39 views
38

Tôi có một cái gì đó dọc theo dòng này:Instantiating một constructor với các thông số trong một lớp học nội với sự phản ánh

object[] parameter = new object[1]; 
parameter[0] = x; 
object instantiatedType = 
Activator.CreateInstance(typeToInstantiate, parameter); 

internal class xxx : ICompare<Type> 
{ 
    private object[] x; 

    # region Constructors 

    internal xxx(object[] x) 
    { 
     this.x = x; 
    } 

    internal xxx() 
    { 
    } 

    ... 
} 

Và tôi nhận được:

ném ngoại lệ: Hệ thống .MissingMethodException: Constructor trên loại 'xxxx.xxx' không được tìm thấy ..

Bất kỳ ý tưởng nào?

+0

Tôi ban đầu mặc dù bạn dự định 'tham số' là điều bạn đã chuyển thành' x'. Tuy nhiên, tôi chỉ nhận ra rằng đó không phải là ý của bạn và, nhìn vào những câu trả lời khác, có vẻ như tôi không đơn độc. Nếu điều này đúng, tôi đề nghị đổi tên 'tham số' thành' tham số'. Hoặc vẫn tốt hơn, phân phối với 'tham số' hoàn toàn:' Activator.CreateInstance (typeToInstantiate, new object [] {x}) '. –

Trả lời

75

Vấn đề là Activator.CreateInstance(Type, object[]) không xem xét nhà xây dựng ngoài công lập.

Exceptions

MissingMethodException: Không phù hợp với constructor nào được tìm thấy.

Điều này dễ dàng được hiển thị bằng cách thay đổi hàm tạo thành hiển thị public; sau đó mã hoạt động chính xác.

Dưới đây là một workaround (thử nghiệm):

BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; 
CultureInfo culture = null; // use InvariantCulture or other if you prefer 
object instantiatedType = 
    Activator.CreateInstance(typeToInstantiate, flags, null, parameter, culture); 

Nếu bạn chỉ yêu cầu các nhà xây dựng parameterless này sẽ làm việc tốt:

//using the overload: public static object CreateInstance(Type type, bool nonPublic) 
object instantiatedType = Activator.CreateInstance(typeToInstantiate, true) 
+0

hầu hết tất cả các câu trả lời của bạn đều hợp lệ, cảm ơn. – KP65

+0

Tôi nên đánh dấu trang này. –

+10

Tôi đã thử nghiệm điều này và nghĩ rằng điều đáng nói đến là phương pháp này CHỈ làm việc với các nhà thầu ngoài công lập. Để làm cho nó hoạt động với cả các hàm tạo công khai và không công khai, hãy thay đổi 'BindingFlags' thành' BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance' – ken

1

thay đổi nó để

Activator.CreateInstance(typeToInstantiate,new object[] { parameter }); 

Điều này là do nhà xây dựng của bạn cũng hy vọng một mảng đối tượng và activator đã chia nó lên thành các đối tượng riêng biệt

3

Bạn cần phải gọi a different overload of Activator.CreateInstance cho phép bạn vượt qua một nonPublic hoặc Tham số BindingFlags.

Tôi tìm thấy tất cả các trường hợp quá tải CreateInstance quá tải này vụng về; những gì tôi thích làm là:

  1. Gọi typeToInstantiate.GetConstructor(), đi qua BindingFlags.NonPublic
  2. Gọi ConstructorInfo.Invoke, truyền cho nó các tham số constructor
18

(thử nghiệm thành công)

object instantiatedType = 
    Activator.CreateInstance(typeToInstantiate, 
    System.Reflection.BindingFlags.NonPublic | 
    System.Reflection.BindingFlags.Instance, 
    null, new object[] {parameter}, null); 

Có hai vấn đề địa chỉ này:

  • các new object[] {parameter} giúp nó xử lý vấn đề của truyền một object[] như một đơn tham số của phương pháp mà có một cuộc tranh luận params object[]
  • các BindingFlags giúp giải quyết các nhà xây dựng ngoài công lập

(hai null s liên quan đến chất kết dính ; hành vi kết dính mặc định là tốt cho những gì chúng tôi muốn)

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