type泛型 - c#泛型构造函数




将实例化的System.Type传递为泛型类的类型参数 (3)

一些额外的如何使用剪刀代码运行。 假设你有一个类似于

public class Encoder() {
public void Markdown(IEnumerable<FooContent> contents) { do magic }
public void Markdown(IEnumerable<BarContent> contents) { do magic2 }
}

假设在运行时你有一个FooContent

如果你能够在编译时绑定你想要的

var fooContents = new List<FooContent>(fooContent)
new Encoder().Markdown(fooContents)

但是,您无法在运行时执行此操作。 要在运行时执行此操作,您可以按照以下方式进行操作:

var listType = typeof(List<>).MakeGenericType(myType);
var dynamicList = Activator.CreateInstance(listType);
((IList)dynamicList).Add(fooContent);

要动态调用Markdown(IEnumerable<FooContent> contents)

new Encoder().Markdown( (dynamic) dynamicList)

请注意方法调用中的dynamic使用情况。 在运行时, List<FooContent>将是List<FooContent> (另外也是IEnumerable<FooContent> ),因为即使使用动态仍然植根于强类型语言,运行时活页夹将选择适当的Markdown方法。 如果没有确切的类型匹配,它将查找对象参数方法,如果两者都不匹配,则会引发运行时绑定程序异常,提示没有方法匹配。

这种方法显而易见的缺点是编译时类型安全性的巨大损失。 尽管如此,代码沿着这些线将允许您以非常动态的方式运行,即在运行时仍可完全键入您所期望的类型。

标题有点模糊。 我想知道的是,如果这是可能的:

string typeName = <read type name from somwhere>;
Type myType = Type.GetType(typeName);

MyGenericClass<myType> myGenericClass = new MyGenericClass<myType>();

显然,MyGenericClass被描述为:

public class MyGenericClass<T>

现在,编译器抱怨'找不到类型或名称空间'myType'。“必须有一种方法可以做到这一点。


不幸的是,没有。 通用参数必须在编译时可解析为1)有效类型或2)另一个通用参数。 如果没有使用反射的大锤,没有办法基于运行时值创建泛型实例。


没有反思,你不能这样做。 但是,你可以用反射做到这一点。 这是一个完整的例子:

using System;
using System.Reflection;

public class Generic<T>
{
    public Generic()
    {
        Console.WriteLine("T={0}", typeof(T));
    }
}

class Test
{
    static void Main()
    {
        string typeName = "System.String";
        Type typeArgument = Type.GetType(typeName);

        Type genericClass = typeof(Generic<>);
        // MakeGenericType is badly named
        Type constructedClass = genericClass.MakeGenericType(typeArgument);

        object created = Activator.CreateInstance(constructedClass);
    }
}

注意:如果您的泛型类接受多种类型,则在省略类型名称时必须包含逗号,例如:

Type genericClass = typeof(IReadOnlyDictionary<,>);
Type constructedClass = genericClass.MakeGenericType(typeArgument1, typeArgument2);






generics