定义嵌套的无界泛型类型

时间:2012-02-24 15:46:04

标签: c# generics

假设我有一个界面:IFoo<T1,T2>和一个类Moo<T1> : IFoo<List<T1>, Stack<T1>>

在运行时我可以调用:typeof(Moo<>).GetInterfaces()并且它为我提供了一个包含一种类型的数组,所以我想在某种意义上可以在运行时创建类型typeof(IFoo<List<>, Stack<>>)。但是,该语法不起作用。

在运行时定义该类型的正确语法是什么?

5 个答案:

答案 0 :(得分:7)

  

我想在某种意义上,可以在运行时创建类型typeof(IFoo<List<>, Stack<>>)

虽然该陈述是 true ,但你的逻辑不是声音,因为真正的结论并不符合你所陈述的前提。

返回的类型
typeof(Moo<>).GetInterfaces()[0]

首先不是IFoo<T1, T2>List<>构建的Stack<>

而是由IFoo<T1, T2>List<T1>构建的Stack<T1>,其中T1T1的{​​{1}},而不是Moo<T1> 1 {} T1。在制作示例代码以讨论类型构造时,我强烈建议您不要生成逻辑上不同但名称相同的类型参数。这非常令人困惑。

如果不清楚,让我们退后一步。每个泛型类型都有一个名为实例类型的关联类型,它是使用自己的类型参数构造的泛型类型。也就是说,当你说:

IFoo<T1, T2>

编译器的角度来看,类型 class C<T> { Type type1 = typeof(C<T>); Type type2 = typeof(C<>); } C<>属于同一类型。但是这些运行时的不同类型对象,因为当然在运行时,永远不会有C<T>的实例,只有C<T>C<int>或其他任何实例。第一个C<string>语法为您提供了在运行时构建的类型。第二个从编译器的角度为您提供实例类型

因此,让我们更详细地考虑您的情况。假设你有:

typeof

然后interface I<T, U> {} class C<V> {} class D<W> {} class E<X> : I<C<X>, D<X>> {} 类型,因为编译器已知,即typeof(E<>).GetInterfaces()[0]。但是I<C<X>, D<X>>是完全不同的类型;那是I<C<>, D<>>,从编译器的角度来看,它完全不是同一类型。

  

在运行时定义该类型的正确语法是什么?

没有。

没有C#I<C<V>, D<W>>语法生成类型“使用类型参数构造的泛型类型,类型参数是其他泛型类型的实例类型”。那将是:

typeof

给你typeof(I<,>).MakeGenericType(typeof(C<>), typeof(D<>))

“使用不同泛型类型的类型参数构造的泛型类型”也没有I<C<V>, D<W>>语法。 kvb的答案给出了构建typeof所需的反射代码。

我很好奇为什么你想要首先构建这种奇怪的类型。你的申请是什么?

答案 1 :(得分:2)

我猜你必须使用typeof(IFoo<,>).MakeGenericType(typeof(List<>), typeof(Stack<>));

答案 2 :(得分:1)

你无法在那个细节中真正定义它。您可以定义类型的基础,然后对其进行扩展,如下所示:

Type d1 = typeof(IFoo<,>);
Type constructed = d1.MakeGenericType(typeof(List<>), typeof(Stack());

答案 3 :(得分:1)

这可能就是你要找的东西:

typeof(IFoo<,>).MakeGenericType(typeof(List<>),typeof(Stack<>))

答案 4 :(得分:0)

我不完全确定我理解你的要求,但是

var t1 = typeof(Moo<>).GetGenericArguments()[0];
var t = typeof(IFoo<,>).MakeGenericType(typeof(List<>).MakeGenericType(t1), typeof(Stack<>).MakeGenericType(t1));

应该与typeof(Moo<>).GetInterfaces()[0]给出相同的结果。