我需要创建这样一个泛型类的实例:
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*/}
}
发布于 2017-05-11 17:18:12
我找到了非常简单的解决问题的方法。不需要将object
转换为特定类型的T
,只需使用dynamic
关键字而不是强制转换。
Type myGeneric = typeof(MyComparer<>);
Type constructedClass = myGeneric.MakeGenericType(T);
object created = Activator.CreateInstance(constructedClass);
dynamic comparer = created; // No need to cast created object to T
然后,我可以正常地使用比较器调用它的方法,例如:
return comparer.Equals(myResultAsT, correctResultAsT);
根据LueTm注释,很可能再次使用反射并调用比较器方法,但是这个解决方案看起来要容易得多。
发布于 2017-05-10 18:10:56
看起来你就快到了
// t is a variable, so make it lowercase. This is where some of the confusion comes from
Type t = Type.GetType(className).GetMethod(functionName).ReturnType;
Type myGeneric = typeof(IEqualityComparer<>);
// You need to provide the generic type to make it generic with
// You want IEqualityComparer<T>, so:
Type constructedClass = myGeneric.MakeGenericType(t);
// Now create the object
object created = Activator.CreateInstance(constructedClass);
// This is tricky without more context...
// You could try this, but to tell you more I would need to know where you use
// the comparer instance. Are you using it in a LINQ query, or in a Sort()?
// If so just cast it to a IEqualityComparer<YourType>, and
// make YourType whaterver you need it to be in the list or the query...
var comparer = (IEqualityComparer<object>)created;
https://stackoverflow.com/questions/43899490
复制相似问题