定义嵌套的无界泛型类型

本文关键字:泛型类型 嵌套 定义 | 更新日期: 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>构造的,其中T1Moo<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]相同的结果。