2014-01-05 26 views
0

我試圖使用Activator.CreateInstance方法來動態地創建一個新的實例。但是當我將可隱式轉換的類的實例傳遞給實際類型(在構造函數中)時,我得到System.MissingMethodException的。 下面是我使用來驗證我的測試代碼:當我通過在派生類實例(這也是在上面的代碼)發生Activator.CreateInstance不工作的隱式轉換場景

using System; 

    namespace ActivatorTest1 
    { 
     class Program 
     { 
      static void Main(string[] args) 
      { 
       Test t = new Test(new string[] { "abc" }); 
       NewClass nc = new NewClass(new SubTest("apple")); 
       NewClass2 nc2 = nc; 
       try 
       { 
        Object[] paramList = new object[] { nc }; // nc is an instance of NewClass, which is implicitly castable to NewClass2 
        Activator.CreateInstance(typeof(Test), paramList); 
        Console.WriteLine("Instance successfully created"); 
        Console.WriteLine("**************************"); 
       } 
       catch (Exception exc) 
       { 
        Console.WriteLine("INSTANCE CREATION FAILED FOR IMPLICIT CASTING SCENARIO. \r\n\r\n " + exc); 
       } 

       Console.WriteLine("\r\n\r\n\r\n****************************************************\r\n\r\n\r\n"); 
       try 
       { 
        Object[] paramList = new object[] { t }; // Although t is an instance of Test which is the base class for SubTest, MissingConstructorException is thrown 
        Activator.CreateInstance(typeof(NewClass), paramList); 
        Console.WriteLine("Instance successfully created"); 
        Console.WriteLine("**************************"); 
       } 
       catch (Exception exc) 
       { 
        Console.WriteLine("INSTANCE CREATION FAILED FOR DERIVED CLASS SCENARIO. \r\n " + exc); 
       } 
       Console.ReadKey(); 
      } 
     } 

     class Test 
     { 
      public Test(string[] strArr) 
      { } 

      public Test(NewClass2 nc2) 
      { } 
     } 

     class SubTest : Test 
     { 
      public SubTest(string str) 
       : base(new string[] { str }) 
      { } 
     } 

     class NewClass // implicitly castable to NewClass2 
     { 
      public NewClass(SubTest st) 
      { } 
     } 

     class NewClass2 
     { 
      public NewClass2() 
      { } 

      public static implicit operator NewClass2(NewClass nc) 
      { 
       return new NewClass2(); 
      } 
     } 
    } 

同樣的事情。所以,這是預期的行爲還是我在我的代碼中做錯了什麼。這種情況的正確方法是什麼?謝謝。

編輯:關於第二部分,我的實現是錯誤的(如下面的答覆中提到),一旦代碼被相應的修改,使用派生類作爲參數成功創建所需的實例。 但是,關於隱式鑄造的情況,仍然需要一個解決方法。也許有一些與模式相關的解決方案,或者一些棘手的/冒險的實現,即使對於隱式可轉換類型也會生成一個新實例?

回答

1

對於第一種方案:

Activator.CreateInstance(typeof(Test), new object[] { new NewClass(...) }); 

,因爲該類Test沒有構造函數取NewClass類型的一個參數,這種調用失敗。 編輯:您定義了一個隱式轉換運算符,但這不與Activator類的反射方法一起使用,因爲它正在搜索Test上的構造函數,該函數採用類型爲NewClass的參數,並且失敗。即使通過new操作員創建了作品(因爲演員將在new操作之前評估)。對於反射,編譯器/ clr不知道它需要執行轉換,因爲它只查看類型。

也許你打算調用構造函數與NewClass2:因爲你需要傳遞的SubTest而不是Test實例

Activator.CreateInstance(typeof(Test), new object[] { new NewClass2(...) }); 

第二次調用失敗。另一種方式可以(如果你需要Test並且你通過SubTest)。

Activator.CreateInstance(typeof(NewClass), new object[] { new SubTest(...) }); 

MissingMethodException就在這一點上是因爲你試圖調用未被定義的構造函數。

+0

關於基礎派生類場景,是的,你是對的,我修改了ctor後,實例創建成功。 對於隱式轉換的情況下,不像你說的話, *測試T1 =新的測試(新的NewClass()); * 編譯成功。但只通過** Reflection **創建實例時失敗。 如果這是Activator.CreateInstance工作的理想方式,那麼爲什麼會是我的下一個問題(關於內部工作的一些解釋會有幫助)。 – MrClan

+0

NewClass2和NewClass在任何意義上都不是繼承的鏈接器,測試沒有NewClass的代碼,所以你發佈的代碼無法工作。一秒鐘,我會解釋爲什麼... – Matten

+0

@MrClan更新了我的答案 - 希望這可以爲你解決問題。 – Matten