如何创建构造的泛型类型,而无需指定任何类型参数



当我们有这样的代码时:

interface ISomething<U,V> { ... }
class Something<U,V> : ISomething<U,V> { ... }

typeof(ISomething<,>)typeof(Something<,>)将产生"泛型类型定义"。但是,如果我们把接口类型作为类实现的接口,它将是一个构造类型,它的类型参数实际上都没有绑定:

typeof(Something<,>).GetInterfaces().SingleOrDefault()

MSDN特别提到了这一点。我想要的,是直接构建ISomething<,>的相同类型(构造类型)(没有子类化和他们寻找基类型),我找不到任何方法来做到这一点。

额外的信息:

我甚至试过这个:

Type t1 = typeof(ISomething<,>);
Type t2 = t1.MakeGenericType(t1.GetGenericArguments()) // Yields a generic type definition
Type t3 = typeof(Something<,>).GetInterfaces().SingleOrDefault();

在以上代码中:

t1.Equals(t2)为真,而t1.Equals(t3)为假,这显然是因为t3是被构造的。

令人惊讶的是,t1.GetGenericArguments()[0].Equals(t3.GetGenericArguments()[0])是假的,尽管两者都是打开的(IsGenericParameter = true),我找不到它们属性的任何差异。

我需要这样做的原因是:我需要一个在列表中存储Type对象的规范形式。这些对象有时来自基类/接口(如上面的t3),有时直接来自基类/接口(如t1)。我需要能够将它们相互比较。我不能存储泛型类型定义(使用.GetGenericTypeDefinition()),因为有时我将有一个部分开放的构造泛型类型(如issomething),并且GetGenericTypeDefinition将给我一个没有指定任何类型参数的类型。

使类型规范化的唯一方法是检查是否所有类型参数都未绑定,并执行GetGenericTypeDefinition。否则保持已构造的类型。

你把自己搞得一团糟。检查这个程序的输出,确保你理解了它。这里我对类型参数进行了字母重命名,这样就不会因为两个都命名为U的东西而造成不清晰:

interface I<S, T>
{
    I<S, T> M();
}
class C<U, V> : I<U, V>
{
    public I<U, V> M() {return null;}
    public C<U, V> N() {return null;}
}
public class MainClass
{
    public static void Main()
    {
        var i1 = typeof(I<,>);
        var i2 = typeof(I<int, int>);
        var i3 = i2.GetGenericTypeDefinition();
        var i4 = i1.GetMethod("M").ReturnType;
        var c1 = typeof(C<,>);
        var c2 = typeof(C<int, int>);
        var c3 = c2.GetGenericTypeDefinition();
        var c4 = c1.GetMethod("N").ReturnType;
        var i5 = c1.GetMethod("M").ReturnType;
        var i6 = c1.GetInterfaces()[0];
        System.Console.WriteLine(i1 == i2); // false -- I<,> is not I<int, int>
        System.Console.WriteLine(i1 == i3); // true  -- I<int,int>'s decl is I<,>
        System.Console.WriteLine(i1 == i4); // true  -- I<,> is I<S, T>
        System.Console.WriteLine(i1 == i5); // false -- I<S, T> is not I<U, V>
        System.Console.WriteLine(i1 == i6); // false -- I<S, T> is not I<U, V>
        System.Console.WriteLine(c1 == c2); // false -- C<,> is not C<int, int>
        System.Console.WriteLine(c1 == c3); // true  -- C<int,int>'s decl is C<,>
        System.Console.WriteLine(c1 == c4); // true  -- C<,> is C<U,V>
    }
}

相关内容

  • 没有找到相关文章

最新更新