C# 是否需要使用MakeGenericType方法?

C# 是否需要使用MakeGenericType方法?,c#,.net,C#,.net,我看到这样的代码: internal sealed class MyDictionary<TKey, TValue> { } public static class Program { public static void Main() { // Get a reference to the generic type's type object Type openType = typeof(MyDictionary<,>);

我看到这样的代码:

internal sealed class MyDictionary<TKey, TValue> { }

public static class Program {
   public static void Main() {
      // Get a reference to the generic type's type object
      Type openType = typeof(MyDictionary<,>);
      
      // Close the generic type by using TKey=String, TValue=Int32
      Type closedType = openType.MakeGenericType(typeof(string), typeof(int));
      
      // Construct an instance of the closed type
      Object o = Activator.CreateInstance(closedType);

      Console.WriteLine(o.GetType());
   }
}
内部密封类MyDictionary{}
公共静态类程序{
公共静态void Main(){
//获取泛型类型的类型对象的引用
类型openType=typeof(MyDictionary);
//使用TKey=String,TValue=Int32关闭泛型类型
Type closedType=openType.MakeGenericType(typeof(string),typeof(int));
//构造封闭类型的实例
对象o=Activator.CreateInstance(closedType);
WriteLine(o.GetType());
}
}
但是为什么我们需要使用MakeGenericType方法,为什么不直接使用:

...
Type concreteType= typeof(MyDictionary<string, int>);

Object o = Activator.CreateInstance(concreteType);

Console.WriteLine(o.GetType());
。。。
类型concreteType=typeof(MyDictionary);
对象o=Activator.CreateInstance(具体类型);
WriteLine(o.GetType());
结果是一样的


看起来
MakeGenericType
方法添加了额外的不必要性,
MakeGenericType
是否提供了我忽略的有用功能?

MakeGenericType
适用于编译时不知道类型的情况。因此,您是正确的-您不会真正使用您看到的代码,因为类型在编译时是已知的,所以您最好编写
newmydictionary()

但是,代码可以这样重写:

internal sealed class MyDictionary<TKey, TValue> { }

public static class Program {
   public static void Main() {
      // Get a reference to the generic type's type object
      Type openType = typeof(MyDictionary<,>);
      
      // Close the generic type by using TKey=String, TValue=Int32
      Type closedType = openType.MakeGenericType(typeof(string), typeof(int));
      
      // Construct an instance of the closed type
      Object o = Activator.CreateInstance(closedType);

      Console.WriteLine(o.GetType());
   }
}
内部密封类MyDictionary{}
公共静态类工厂{
公共静态MyDictionary创建(){
//获取泛型类型的类型对象的引用
类型openType=typeof(MyDictionary);
//使用类型约束关闭泛型类型
Type closedType=openType.MakeGenericType(typeof(TKey)、typeof(TValue));
//构造封闭类型的实例
对象o=Activator.CreateInstance(closedType);
返回(MyDictionary)o;
}
}
这两者将有效地创建相同的对象:

var dictionary 0=new MyDictionary();
var dictionary1=Factory.Create();
Console.WriteLine(dictionary0.GetType()==dictionary1.GetType());
//真的
即使在这里,它也没有那么有用,因为返回类型需要泛型约束。我将其用于需要接口或抽象返回类型,但需要创建通用实现的情况,例如:

内部密封类MyDictionary:ISomeFeature{}
公共静态类工厂{
创建公共静态等轴测功能(类型键、类型值){
//获取泛型类型的类型对象的引用
类型openType=typeof(MyDictionary);
//使用参数关闭泛型类型
Type closedType=openType.MakeGenericType(键,值);
//构造封闭类型的实例
对象o=Activator.CreateInstance(closedType);
返回(等距特征)o;
}
}

现在它突然变得更有用了。因为它依赖于
Type
对象而不是泛型约束,所以您可以动态地传递它的类型-即在运行时。

简短回答:不必使用
makeGenericType
,但有时这是必要的



泛型最好在编译时知道类型时使用。事实上,有一个很好的论点是,如果您在编译时不知道类型,您可能不应该使用泛型

也就是说,有时您需要使用通用实现(可能是第三方库),而您只知道运行时的类型。。。这就是反射,特别是
MakeGenericType
的作用

毫无疑问,您的代码是如何做到这一点的一个示例,因为实际上,该代码只是在

var dict = new MyDictionary<string,int>();
Console.WriteLine(dict.GetType());
var dict=new MyDictionary();
Console.WriteLine(dict.GetType());

假设类型在编译时已知。

我认为这段代码只是一个示例。当您知道
string
int
以及编译时,整个代码都是无用的,可能只是
Object o=new Dictionary()<当您在编译时不知道类型时,code>MakeGenericType
会变得很有用。@RenéVogt-您已经非常简洁地回答了OP。你应该把它作为答案贴出来。你的第一句话很好。其余的只是把事情弄糊涂了。OP有一些特定的代码-我建议您提供的任何示例都应该基于OP的代码。我这样回答,因为问题不是关于他们的代码,而是他们“看到”的一些代码,所以我使用自己代码的一个(工作)示例来解释
MakeGenericType()
的作用-这就是问题所在。“如果你在编译时不知道类型,你可能不应该使用泛型”-我不认为这是一个正确的说法。如果你在运行时不知道类型,使用泛型会更困难。但这是OP问题的关键,我认为你应该解决这个问题。