【发布时间】:2017-05-10 17:48:18
【问题描述】:
我需要像这样创建一个通用类的实例:
Type T = Type.GetType(className).GetMethod(functionName).ReturnType;
var comparer = new MyComparer<T>(); // ERROR: "The type or namespace name 'T' could not be found"
我发现了这个answer,只有通过反射才能做到这一点。但是使用反射我得到了我需要转换为我的泛型类型的对象。我试过这样
Type myGeneric = typeof(MyComparer<>);
Type constructedClass = myGeneric.MakeGenericType();
object created = Activator.CreateInstance(constructedClass);
var comparer = (T)Convert.ChangeType(created, T);// ERROR: "The type or namespace name 'T' could not be found"
但得到同样的错误。如何解决?
这是一个完整的例子:
public static bool Test(string className, string functionName, object[] parameters, object correctResult)
{
var method = Type.GetType(className).GetMethod(functionName);
Type T = method.ReturnType;
var myResult = method.Invoke(null, parameters);
dynamic myResultAsT = Convert.ChangeType(myResult, T);
dynamic correctResultAsT = Convert.ChangeType(correctResult, T);
var comparer = new MyComparer<T>(); // Problem is here!!!
return comparer.Equals(myResultAsT, correctResultAsT);
}
这个想法是做一个单元测试,它将调用一个带参数的函数并将其结果与正确的结果进行比较。但我需要自定义比较器,所以我实现了 MyComparer,由于编译器错误,我无法使用它。
public class MyComparer<T> : IEqualityComparer<T>
{
public bool Equals(T x, T y){/* some implementation*/}
}
【问题讨论】:
-
你的错误信息没有意义,你确定他们是这么说的吗?
-
@DavidG 完整的编译器错误是:
The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)。为什么没有意义? -
那你显示的代码不够,请显示minimal reproducible example
-
首先,C# 中没有“模板”之类的东西。只有泛型。其次,正如您已经看到的,有足够的答案描述了如何基于仅在运行时才知道的类型来实例化泛型类型。第三,当大多数人认为他们需要这个时,他们仍然会在尝试使用动态实例化对象时遇到问题,因为代码仍然需要在编译时知道类型。
-
您实际上似乎有几个不同的问题;我们需要您提供一个很好的minimal reproducible example,清楚地显示目前的one 问题是什么。考虑将其作为您的最高级别问题,即关于单元测试的问题,因为您似乎真的在这里遇到了XY Problem 时刻。如果根本需要动态实例化您的对象,我会感到惊讶。
标签: c# generics reflection casting