使用动态泛型类型参数创建泛型类的实例

Dej*_*jan 4 c# generics reflection casting

我需要像这样创建一个泛型类的实例:

 Type T = Type.GetType(className).GetMethod(functionName).ReturnType;
 var comparer = new MyComparer<T>(); // ERROR: "The type or namespace name 'T' could not be found"
Run Code Online (Sandbox Code Playgroud)

我找到了这个答案,只有通过反射才能做到这一点。但是使用反射我得到了我需要转换为我的泛型类型的对象。我试过这样

 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"
Run Code Online (Sandbox Code Playgroud)

但得到同样的错误。如何解决?

这是一个完整的例子:

    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);            
    }
Run Code Online (Sandbox Code Playgroud)

这个想法是进行一个单元测试,它将调用一个带参数的函数并将其结果与正确的结果进行比较。但是我需要自定义比较器,因此我实现了MyComparer由于编译器错误而无法使用的比较器。

public class MyComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y){/* some implementation*/}
}
Run Code Online (Sandbox Code Playgroud)

Dej*_*jan 5

我找到了非常简单的问题解决方案。无需强制转换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
Run Code Online (Sandbox Code Playgroud)

然后我可以正常使用比较器来调用它的方法,如:

   return comparer.Equals(myResultAsT, correctResultAsT);
Run Code Online (Sandbox Code Playgroud)

根据LueTm 的评论,可能可以再次使用反射并调用比较器方法,但这种解决方案看起来容易得多。