我是 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# 的新手,这是我第一次处理反射和泛型。谢谢!
最佳答案
首先,我建议在调试器中运行此代码并打开一个“异常中断” 以帮助隔离导致错误的行。这是一种有用的调试技巧,可以帮助您在将来更快地找到这些类型的问题。转到 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()
并不意味着它是合适的 - 除非您知道那是正确的行为。 p>
最后,我不知道使用反射调用 MethodInOtherClass
是否有令人信服的理由 - 也许有。但是由于您是 C# 的新手,我会提到如果类型 T
始终是某个基类型 A
的子类,或者将始终实现某个接口(interface) I
包含您要调用的方法,您可以简单地应用通用约束来让编译器知道这一点。然后您可以调用该方法而无需恢复使用反射:
public void UpdateRecords<T>(T sender)
where T : SomeBaseClass_Or_SomeInterface_ThatDefinesMethod
{
sender = new T();
sender.MethodInOtherClass( x, y );
}
好多了。
最后的评论。将参数传递给方法,然后完全忽略它是不常见的——只在方法中实例化一个实例。在某些情况下它是合适的 - 但我倾向于将其视为 code smell .如果可能的话,我会尝试去掉 sender
参数,或者更改代码以首先测试它是否为 null,然后才实例化。
关于c# - .NET 2.0 : Invoking Methods Using Reflection And Generics Causes Exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3040925/