2017-07-26 93 views
3

從WinForms應用程序考慮以下代碼示例:爲什麼方法調用失敗,參數異常?

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      object[] parms = new object[1]; 
      parms[0] = "foo"; 

      DoSomething(parms); 
     } 

     public static string DoSomething(object[] parms) 
     { 
      Console.WriteLine("Something good happened"); 
      return null; 
     } 
    } 

它能正常工作,當您單擊按鈕1 打印「好東西發生」到控制檯。

現在考慮此代碼示例,這是相同的,除了它調用DoSomething使用反射:

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      object[] parms = new object[1]; 
      parms[0] = "foo"; 

      System.Reflection.MethodInfo mi = typeof(Form1).GetMethod("DoSomething"); 
      mi.Invoke(null, parms); 

     } 

     public static string DoSomething(object[] parms) 
     { 
      Console.WriteLine("Something good happened"); 
      return null; 
     } 
    } 

它輕視行mi.Invoke(null, parms)(類型的對象「System.String」的System.ArgumentException不能轉換到鍵入'System.Object []'。)

parms顯然是一個對象數組,而DoSomething的方法簽名顯然是期待一個對象數組。那麼爲什麼調用將第一個對象從數組中拉出並試圖通過它呢?

還是別的什麼事情,我不理解?

回答

7

MethodInfo.Invoke期待一個對象數組,其中對象數組中的每個對象對應一個參數傳遞給方法。對象數組中的第一個參數是第一個參數,數組中的第二個對象是第二個方法等。

由於您希望方法的第一個參數爲object[],因此需要確保第一個對象在傳遞給對象數組的對象數組中MethodInfo.Invoke是一個對象數組,它表示DoSomething應該使用的數組。

+1

這使得現在完美的意義 - 當然它工作的方式。時間離開鍵盤幾分鐘:-) – GojiraDeMonstah

2
object[] parms = new object[1]; 
parms[0] = "foo"; 

有:

public static string DoSomething(object[] parms) 

這就是問題所在;第一個參數不是string - 它是object[]。您傳遞給Invokeobject[]代表每個參數依次爲,因此長度爲1的object[]與字符串匹配將與static string DoSomething(string s)匹配,但與您的方法不匹配。請更改簽名或包裝該值。坦率地說,我建議在這裏更改簽名是更好的主意,但:

parms[0] = new object[] { "foo" }; 

也將工作

1

MethodInfo.Invoke需要一個對象數組作爲參數將多個參數傳遞給函數,數組中的每個對象將是一個不同的參數。

由於您的函數也期望您傳遞的對象數組不是對象數組而是字符串。

您必須將該數組包裝到另一個數組中,這樣Invoke將打開第一個數組,並使用內部數組作爲調用的第一個參數。

mi.Invoke(null, new object[]{ parms }); 
1

parms is clearly an object array, and DoSomething's method signature is clearly expecting an object array.

是它期待一個對象陣列。但是,當你通過這樣的:

object[] parms = new object[1]; 

你是說這些都是爭論的DoSomething所以PARMS [0]是第一個參數DoSomething,如果有在parms了多個項目,然後PARMS [1]將成爲第二爭論等等。

顯然對DoSomething第一個參數是不是string(PARMS [0]),所以你得到這個錯誤:

It throws an System.ArgumentException on the line mi.Invoke(null, parms) (Object of type 'System.String' cannot be converted to type 'System.Object[]'.)

相關問題