.NET 2.0:使用反射和泛型调用方法会导致异常

Ian*_*Ian 2 .net c# generics reflection .net-2.0

我是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);
}
Run Code Online (Sandbox Code Playgroud)

抛出异常:"对象引用未设置为对象的实例."

我再次道歉,因为我几乎是C#的新手,这是我第一次处理反射和泛型.谢谢!

LBu*_*kin 6

首先,我建议在调试器中运行此代码并转换一个"Break on Exception"以帮助隔离哪一行导致错误.这是一种有用的调试技术,可以帮助您在将来更快地找到这些类型的问题.转到Debug >> Exceptions在VS并勾选用于Common Language Runtime ExceptionsThrown列.

现在为你的问题.这可能sender是传入的null.如果是这样,行:

Type foo = Type.GetType(sender.GetType().ToString()); 
Run Code Online (Sandbox Code Playgroud)

会抛出一个NullReferenceException.相反,你可以使用:

Type foo = typeof(T); 
Run Code Online (Sandbox Code Playgroud)

它标识泛型参数的类型,而不需要它的实例.

现在,在不了解您的代码尝试做什么的情况下,无法确定实例化实例是否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 );
}
Run Code Online (Sandbox Code Playgroud)

好多了.

最后一条评论.将参数传递给方法然后完全忽略它是不常见的 - 只是为了在方法中实例化一个实例.有些情况下它是合适的 - 但我倾向于将其视为代码气味.如果可能的话,我会尝试去除sender参数,或者更改代码以首先测试它为null并仅在那时进行实例化.