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

时间:2017-05-10 17:48:19

标签: 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"

我发现这个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*/}
}

1 个答案:

答案 0 :(得分:0)

看起来你几乎就在那里:

// 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;