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

C# 如何在不指定任何类型参数的情况下创建构造的泛型类型,c#,.net,generics,reflection,C#,.net,Generics,Reflection,当我们有这样的东西时: interface ISomething<U,V> { ... } class Something<U,V> : ISomething<U,V> { ... } 接口{…} 类某物:等距某物{…} typeof(Something)和typeof(Something)将产生“泛型类型定义”。但如果我们将接口类型作为类实现的接口,它将是一个构造类型,其类型参数实际上没有绑定: typeof(Something<,>).Ge

当我们有这样的东西时:

interface ISomething<U,V> { ... }
class Something<U,V> : ISomething<U,V> { ... }
接口{…}
类某物:等距某物{…}
typeof(Something)
typeof(Something)
将产生“泛型类型定义”。但如果我们将接口类型作为类实现的接口,它将是一个构造类型,其类型参数实际上没有绑定:

typeof(Something<,>).GetInterfaces().SingleOrDefault()
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();
Type t1=typeof(等轴测);
Type t2=t1.MakeGenericType(t1.GetGenericArguments())//生成泛型类型定义
类型t3=typeof(Something).GetInterfaces().SingleOrDefault();
在上述代码中:

t1.Equals(t2)
为真,但
t1.Equals(t3)
为假,显然是因为构建了
t3

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

这就是为什么我需要这样做:我需要一种在列表中存储类型对象的规范形式。对象有时来自基类/接口(如上面的t3),有时直接来自(如t1)。我需要能够相互比较这些。我无法存储泛型类型定义(使用
.GetGenericTypeDefinition()
),因为有时我会有一个部分打开的构造泛型类型(如ISomething),而GetGenericTypeDefinition会给我一个没有指定任何类型参数的类型


我认为使类型规范化的唯一方法是检查是否所有类型参数都未绑定,并执行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>
    }
}
接口I
{
我是();
}
C班:I
{
公共I M(){return null;}
公共C N(){return null;}
}
公共类主类
{
公共静态void Main()
{
var i1=类型(I);
var i2=类型(I);
var i3=i2.GetGenericTypeDefinition();
var i4=i1.GetMethod(“M”).ReturnType;
var c1=类型(C);
var c2=类型(C);
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——我不是我
System.Console.WriteLine(i1==i3);//true——I的decl是I
System.Console.WriteLine(i1==i4);//true——I是I
System.Console.WriteLine(i1==i5);//false——我不是我
System.Console.WriteLine(i1==i6);//false——我不是我
System.Console.WriteLine(c1==c2);//false--C不是C
System.Console.WriteLine(c1==c3);//true——C的decl是C
System.Console.WriteLine(c1==c4);//true--C是C
}
}

我认为这不起作用:“检查是否所有类型参数都未绑定,然后执行GetGenericTypeDefinition。否则保留构造的类型。”假设您拥有的类型是
I
。所有类型参数都是未绑定的类型参数,但这与
I
的类型不同。Re:“出人意料……”——这一点也不出人意料。我怀疑这一切的混乱部分是因为有两种完全不同的类型,称为“U”和两种完全不同的类型,称为“V”。当然
I
与实现接口列表中的
I
不同;前者由
I
声明的
参数化,另一个由
某物
声明的
参数化。仅仅因为类型参数具有相同的名称并不意味着它们具有相同的类型。如果我有一个构造的
I
,并对其调用GetGenericTypeDefinition(),它会给我
typeof(I)
?没错,我混淆了两者。事实上,我刚刚知道为什么要构造基类型!我需要更多地思考我原来的问题,。。。但我认为我仍然需要一些方法来比较(或在列表中查找类型),一些行话可能会有所帮助。以正确顺序使用自己的泛型类型参数构造的泛型类型称为“实例类型”。因此,如果您有
接口I{im();}
,那么
typeof(I)
typeof(I).GetMethod(“M”).ReturnType
是相同的类型;它们都是实例类型。也就是说,它们是
I
的类型对象,由它自己声明的类型参数
S
T
构建。谢谢Eric,你太棒了。我意识到我的错误,但是你的示例代码很棒。我想我可以通过传递类的泛型参数来生成我想要的类型,以便在接口之外生成GenericType,即
t1.MakeGenericType(typeof(Something).GetGenericArguments())
。我说得对吗不过,我知道这对我原来的问题没有帮助。@不客气。你不会相信像这样的问题我们必须在编译器中解决。它可能会变得非常混乱!我能问一个问题吗?到目前为止,我在Genrics方面做得不多,所以我想知道它们有什么好处?它们(创建、使用…)有什么意义?泰铢answer@Mitja:你当然可以问一个问题。通过发布一个问题来做到这一点。这就是整个网站的目的!试着用谷歌搜索你的问题,有很多资料可供你参考