发布
社区首页 >问答首页 >使用动态泛型类型参数创建泛型类实例

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

Stack Overflow用户
提问于 2017-05-10 17:48:18
回答 2查看 9.6K关注 0票数 5

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

代码语言:javascript
代码运行次数:0
复制
 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。但是使用反射,我得到了对象,我需要将其转换为泛型类型。我试过像这样

代码语言:javascript
代码运行次数:0
复制
 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"

但也有同样的错误。如何解决这个问题?

下面是一个完整的例子:

代码语言:javascript
代码运行次数:0
复制
    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,因为编译器错误而不能使用它。

代码语言:javascript
代码运行次数:0
复制
public class MyComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y){/* some implementation*/}
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-11 17:18:12

我找到了非常简单的解决问题的方法。不需要将object转换为特定类型的T,只需使用dynamic关键字而不是强制转换。

代码语言:javascript
代码运行次数:0
复制
   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

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

代码语言:javascript
代码运行次数:0
复制
   return comparer.Equals(myResultAsT, correctResultAsT);

根据LueTm注释,很可能再次使用反射并调用比较器方法,但是这个解决方案看起来要容易得多。

票数 6
EN

Stack Overflow用户

发布于 2017-05-10 18:10:56

看起来你就快到了

代码语言:javascript
代码运行次数: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;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43899490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档