假设我有一个界面:IFoo<T1,T2>
和一个类Moo<T1> : IFoo<List<T1>, Stack<T1>>
。
在运行时我可以调用:typeof(Moo<>).GetInterfaces()
并且它为我提供了一个包含一种类型的数组,所以我想在某种意义上可以在运行时创建类型typeof(IFoo<List<>, Stack<>>)
。但是,该语法不起作用。
在运行时定义该类型的正确语法是什么?
答案 0 :(得分:7)
我想在某种意义上,可以在运行时创建类型
typeof(IFoo<List<>, Stack<>>)
。
虽然该陈述是 true ,但你的逻辑不是声音,因为真正的结论并不符合你所陈述的前提。
返回的类型typeof(Moo<>).GetInterfaces()[0]
首先不是IFoo<T1, T2>
和List<>
构建的Stack<>
。
而是由IFoo<T1, T2>
和List<T1>
构建的Stack<T1>
,其中T1
是T1
的{{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]
给出相同的结果。