c# - 如何在不指定任何类型参数的情况下创建构造泛型类型

标签 c# .net generics reflection

当我们遇到这样的事情时:

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

typeof(ISomething<,>)typeof(Something<,>)将导致“通用类型定义”。但是如果我们得到接口(interface)类型作为类实现的接口(interface),它将是一个构造类型,它的类型参数都没有实际绑定(bind):

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 对象的规范形式。对象有时来自基类/接口(interface)(如上面的t3),有时直接来自(如t1)。我需要能够将这些相互比较。我无法存储泛型类型定义(使用 .GetGenericTypeDefinition() ),因为有时我会有一个部分开放的构造泛型类型(如 ISomething),而 GetGenericTypeDefinition 会给我一个没有指定任何类型参数的类型。

我认为使类型规范化的唯一方法是检查所有类型参数是否未绑定(bind),然后执行 GetGenericTypeDefinition。否则保留构造类型。

最佳答案

你把自己弄得一团糟。检查这个程序的输出并确保你理解它。在这里,我对类型参数进行了 alpha 重命名,这样就不会因为两个都命名为 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>
    }
}

关于c# - 如何在不指定任何类型参数的情况下创建构造泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6711106/

相关文章:

c# - AppDomain,运行程序集 .exe 或 .dll?

c# - 将通用类型对象转换为子类型

c# - 动态替换 MVC 4 中的标签

c# - 获取有关 DataSet 中 DataRelations 的信息

C# NPOI Excel 工具不删除行?

.net - 如何通过 SDK 将附件添加到工作项而不使用物理文件?

c# - MVVM ViewModel 很多属性

java - 通过使用泛型传递类来返回类型化类的正确 Java 类型

templates - 如何在 C++/CLI 中使用模板化的通用约束

c# - 通用应用程序缺少 WriteableBitmap SaveJpeg