定义嵌套的无界泛型类型
本文关键字:泛型类型 嵌套 定义 | 更新日期: 2023-09-27 18:25:54
假设我有一个接口:IFoo<T1,T2>
和一个类Moo<T1> : IFoo<List<T1>, Stack<T1>>
。
在运行时我可以调用:typeof(Moo<>).GetInterfaces()
,它给了我一个包含一种类型的数组,所以我想在某种意义上可以在运行时创建类型 typeof(IFoo<List<>, Stack<>>)
。但是,该语法不起作用。
在运行时定义该类型的正确语法是什么?
我想在某种意义上,可以在运行时创建类型
typeof(IFoo<List<>, Stack<>>)
。
虽然这种说法是正确的,但你的逻辑是不合理的,因为真正的结论不是从你所说的前提逻辑上得出的。返回的类型
typeof(Moo<>).GetInterfaces()[0]
首先不是用List<>
和Stack<>
IFoo<T1, T2>
构建的。
相反,它IFoo<T1, T2>
用List<T1>
和Stack<T1>
构造的,其中T1
是Moo<T1>
的T1
,而不是IFoo<T1, T2>
的T1
。在制作示例代码来讨论类型构造时,我强烈建议您不要创建逻辑上不同但具有相同名称的类型参数。这是非常令人困惑的。
如果不清楚,让我们退后一步。每个泛型类型都有一个称为其实例类型的关联类型,该实例类型是使用自己的类型参数构造的泛型类型。也就是说,当你说:
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<>>
是一种完全不同的类型;从编译器的角度来看,这I<C<V>, D<W>>
根本不是同一类型。
在运行时定义该类型的正确语法是什么?
没有。
没有 C# typeof
语法生成类型"使用类型参数构造的泛型类型,这些参数是其他泛型类型的实例类型"。那将是:
typeof(I<,>).MakeGenericType(typeof(C<>), typeof(D<>))
给你I<C<V>, D<W>>
.
"使用不同泛型类型的类型参数构造的泛型类型"也没有typeof
语法。 KVB的回答给出了构建I<C<X>, D<X>>
所需的反射代码。
我很好奇你为什么首先要构建这样一个奇怪的类型。您的应用是什么?
我想你必须使用typeof(IFoo<,>).MakeGenericType(typeof(List<>), typeof(Stack<>));
你无法真正详细定义它。您可以定义类型的基础,然后对其进行扩展,如下所示:
Type d1 = typeof(IFoo<,>);
Type constructed = d1.MakeGenericType(typeof(List<>), typeof(Stack());
这可能是您要查找的内容:
typeof(IFoo<,>).MakeGenericType(typeof(List<>),typeof(Stack<>))
我不完全确定我是否理解你在问什么,但是
var t1 = typeof(Moo<>).GetGenericArguments()[0];
var t = typeof(IFoo<,>).MakeGenericType(typeof(List<>).MakeGenericType(t1), typeof(Stack<>).MakeGenericType(t1));
应该给出与typeof(Moo<>).GetInterfaces()[0]
相同的结果。