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

C# 使用动态泛型类型参数创建泛型类的实例,c#,generics,reflection,casting,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" 看起来你就快到了: // t is a variable, so make it lowercase. Th

我需要创建一个泛型类的实例,如下所示:

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

看起来你就快到了:

// 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;
//t是一个变量,所以将其设置为小写。这就是一些困惑的来源
Type t=Type.GetType(className).GetMethod(functionName).ReturnType;
类型myGeneric=typeof(IEqualityComparer);
//您需要提供泛型类型以使其具有泛型
//您需要iQualityComparer,因此:
类型constructedClass=myGeneric.MakeGenericType(t);
//现在创建对象
创建的对象=Activator.CreateInstance(constructedClass);
//如果没有更多的上下文,这是很棘手的。。。
//你可以试试这个,但为了告诉你更多,我需要知道你在哪里使用
//比较器实例。您是在LINQ查询中使用它,还是在Sort()中使用它?
//如果是这样,请将其提交给IEqualityComparer,然后
//在列表或查询中键入所需的内容。。。
var comparer=(IEqualityComparer)已创建;

我找到了解决这个问题的非常简单的方法。无需将
对象
强制转换为特定类型
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

根据评论,可能可以再次使用反射并调用比较器方法,但此解决方案看起来更简单。

您的错误消息没有意义,您确定他们是这么说的吗?@DavidG Full compiler错误是:
找不到类型或命名空间名称“t”(是否缺少using指令或程序集引用?
。为什么没有意义?如果没有显示足够的代码,请先显示一个,没有“模板”之类的东西在C#中,只有泛型。其次,正如您已经看到的,有足够的答案描述如何基于仅在运行时已知的类型实例化泛型类型。第三,大多数人在认为需要时发现,他们在尝试使用动态实例化对象时仍然遇到问题,因为代码仍然需要修改在编译时,这个类型。实际上你有几个不同的问题,我们需要你提供一个清楚地说明当前的问题是什么。考虑这是你的最高级别的问题,也就是关于单元测试的问题,因为看起来你真的有一个时间在这里。如果DYNA,我会感到惊讶。完全需要对对象进行mical实例化。现在,它正在编译,但在运行时抛出InvalidCastException。
无法将类型为“myCompare1[System.Double]”的对象强制转换为类型为“myCompare1[System.object]“.
我使用MyComparer而不是IEqualityComparer。我只对两个对象的
Equals
使用comparer实例。我没有在LINQ查询中使用它。我在编辑的问题中编写comparer的用法。只要调用Equals方法并进行反射,它就会工作。如果需要帮助,只要编写,我就会编辑t。”他回答。不需要反射和强制转换,我找到了非常简单的解决方案:
dynamiccomparer=created;
然后从comparer调用Equals,它将编译并工作。这绝对是更好的解决方案。@Dejan这(T)从何而来?“MakeGenericType(T);”我在您的代码段中没有看到它。@metabuddy请阅读问题的第一个代码段(第1行)。在我的例子中,t是某个方法的返回类型,但可以是任何类型。
public class MyComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y){/* some implementation*/}
}
// 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;
   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);