我是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#的新手,这是我第一次处理反射和泛型。谢谢!
答案 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)
或者:
sender
为空,因此sender.GetType()
将失败。foo.GetMethod("MethodInOtherClass")
返回null,因此populateMethod.Invoke()
将失败。MethodInOtherClass
取决于某些先决条件(非空引用),因此当它们不存在时它将失败。