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

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

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

我发现这个答案只有通过反思才能实现。 但是使用reflection我得到了我需要转换为我的generics类型的对象。 我试过这样的

  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(); // Problem is here!!! return comparer.Equals(myResultAsT, correctResultAsT); } 

我们的想法是进行unit testing,该测试将使用参数调用函数并将其结果与正确的结果进行比较。 但是我需要自定义比较器,所以我实现了MyComparer ,由于编译错误我无法使用它。

 public class MyComparer : IEqualityComparer { public bool Equals(T x, T y){/* some implementation*/} } 

我找到了解决问题的简单方法。 不需要将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 

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

  return comparer.Equals(myResultAsT, correctResultAsT); 

根据LueTm的评论,可能再次使用reflection并调用比较器方法,但这个解决方案看起来更容易。

看起来你几乎就在那里:

 // 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, 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, and // make YourType whaterver you need it to be in the list or the query... var comparer = (IEqualityComparer)created;