2010-06-14 68 views
2

我是Stack Overflow的新手,所以請原諒。我剛剛開始過渡到C#,我陷入了一個問題。.NET 2.0:調用使用反射和泛型的方法導致異常

我想通過一個泛型類並調用該類的方法。所以,我的代碼看起來像這樣:

public void UpdateRecords<T>(T sender) where T : new() //where T: new() came from Resharper 
{ 
    Type foo = Type.GetType(sender.GetType().ToString()); 
    object[] userParameters = new object[2]; 
    userParameters[0] = x; 
    userParameters[1] = y; 
    sender = new T(); //This was to see if I could solve my exception problem 
    MethodInfo populateRecord = foo.GetMethod("MethodInOtherClass"); 
    populateMethod.Invoke(sender, userParameters); 
} 

拋出的異常:「未將對象引用設置爲對象實例」。

再一次,我真的很抱歉,因爲我幾乎是C#的全新人物,這是我第一次處理反射和泛型。謝謝!

+3

究竟拋出異常在哪裏? – Femaref 2010-06-14 21:10:27

回答

6

首先,我會建議在調試器中運行該代碼並打開一個上異常「打破「,以幫助隔離哪條線路導致錯誤。這是一種有用的調試技術,可以幫助您在將來更迅速地找到這些類型的問題。在VS中轉到Debug >> Exceptions,然後在Thrown列中選中Common Language Runtime Exceptions複選框。

現在爲您的問題。可能sender作爲null被傳入。如果是這樣,該行:

Type foo = Type.GetType(sender.GetType().ToString()); 

將拋出一個NullReferenceException。相反,您可以使用:

Type foo = typeof(T); 

它標識通用參數的類型而不需要它的一個實例。

現在,不知道你的代碼試圖做什麼,不可能說是否實例化一個T的實例是正確的。 僅僅因爲ReSharper建議添加where T : new()並不意味着它是合適的 - 除非你知道這是正確的行爲

最後,我不知道是否有一個令人信服的理由使用反射來調用MethodInOtherClass - 也許有。但是由於您剛剛接觸C#,因此我會提及,如果T類型始終是某個基本類型A的子類,或者將始終實現一些包含要調用的方法的接口I,則可以簡單地應用通用約束讓編譯器知道這一點。然後你可以調用該方法而不回覆到使用反射:

public void UpdateRecords<T>(T sender) 
    where T : SomeBaseClass_Or_SomeInterface_ThatDefinesMethod 
{ 
    sender = new T(); 
    sender.MethodInOtherClass(x, y); 
} 

更好。

最後一個評論。將一個參數傳遞給一個方法是很常見的,然後完全忽略它 - 只是爲了在方法中實例化一個實例。有些情況適用 - 但我傾向於將其視爲code smell。如果可能的話,我會嘗試擺脫sender參數,或者將代碼更改爲首先對其進行測試,然後僅對其進行實例化。

1

你就應該能夠做到這一點,以獲得類型:

Type foo = typeof(T); 

你沒有指定你得到的NullReferenceException,但我想知道,如果富是回來爲空。 ...

2

sender.GetType().ToString()返回類型名稱沒有程序集名稱。

Type.GetType預計類型名稱程序集名稱(除非類型在正在執行的程序集或mscorlib中)。如果找不到類型(例如,由於缺少程序集名稱),它將返回空引用。


試着改變你的代碼

Type foo = sender.GetType(); 

甚至只是

Type foo = typeof(T); 
0

或者:

  1. sender爲空,所以sender.GetType()將失敗。
  2. foo.GetMethod("MethodInOtherClass")返回null,所以populateMethod.Invoke()將失敗。
  3. MethodInOtherClass依賴於某些先決條件(非空引用),所以當它們不存在時它會失敗。