[英].NET 2.0: Invoking Methods Using Reflection And Generics Causes Exception
我是Stack Overflow的新手,請原諒我。 我剛開始轉移到C#,我遇到了問題。
我想傳遞一個泛型類並從該類調用一個方法。 所以,我的代碼看起來像這樣:
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#的新手,這是我第一次處理反射和泛型。 謝謝!
首先,我建議在調試器中運行此代碼並轉換一個“Break on Exception”以幫助隔離哪一行導致錯誤。 這是一種有用的調試技術,可以幫助您在將來更快地找到這些類型的問題。 轉到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 );
}
好多了。
最后一條評論。 將參數傳遞給方法然后完全忽略它是不常見的 - 只是為了在方法中實例化一個實例。 有些情況下它是合適的 - 但我傾向於將其視為代碼氣味 。 如果可能的話,我會嘗試去除sender
參數,或者更改代碼以首先測試它為null並僅在那時進行實例化。
sender.GetType().ToString()
返回沒有程序集名稱的類型名稱。
Type.GetType
預計與組件名稱的類型名稱(除非類型是在執行的程序集或mscorlib程序)。 如果找不到類型(例如,由於缺少程序集名稱),則返回空引用。
嘗試將代碼更改為
Type foo = sender.GetType();
甚至只是
Type foo = typeof(T);
你應該能夠做到這一點來獲得類型:
Type foo = typeof(T);
你沒有指定你獲得NullReferenceException的位置,但我想知道foo是否會返回null ...
或者:
sender
為null,因此sender.GetType()
將失敗。 foo.GetMethod("MethodInOtherClass")
返回null,因此populateMethod.Invoke()
將失敗。 MethodInOtherClass
依賴於某些前提條件(非空引用),因此當它們不存在時它將失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.