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

时间:2010-06-14 21:05:38

标签: c# .net 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);
}

抛出异常:“对象引用未设置为对象的实例。”

同样,我真的很抱歉,因为我几乎是C#的新手,这是我第一次处理反射和泛型。谢谢!

4 个答案:

答案 0 :(得分:6)

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

现在为您解决问题。 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

好多了。

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

答案 1 :(得分:2)

sender.GetType().ToString()返回类型名称,不含程序集名称。

Type.GetType期望类型名称的程序集名称(除非该类型在执行程序集或mscorlib中)。如果找不到类型(例如,由于缺少程序集名称),则返回空引用。


尝试将代码更改为

Type foo = sender.GetType();

甚至只是

Type foo = typeof(T);

答案 2 :(得分:1)

你应该能够做到这一点来获得类型:

Type foo = typeof(T);

您没有指定获取NullReferenceException的位置,但我想知道foo是否会返回null ...

答案 3 :(得分:0)

或者:

  1. sender为空,因此sender.GetType()将失败。
  2. foo.GetMethod("MethodInOtherClass")返回null,因此populateMethod.Invoke()将失败。
  3. MethodInOtherClass取决于某些先决条件(非空引用),因此当它们不存在时它将失败。