如何为C#中的泛型约束获取有效的类型对象?

如何为C#中的泛型约束获取有效的类型对象?,c#,generics,reflection,C#,Generics,Reflection,Im正在尝试使用反射解析程序集中提供的数据。在我的场景中,我试图找出泛型参数可能具有的约束类型。在这里,我遇到了一个非常奇怪的问题:泛型约束确实返回了一个残缺的类型对象 让我与您分享这段代码: public class GenericTest { public class MyGenericClass<T, U, V> where T : System.IO.StringReader where U : System.IO.StringWri

Im正在尝试使用反射解析程序集中提供的数据。在我的场景中,我试图找出泛型参数可能具有的约束类型。在这里,我遇到了一个非常奇怪的问题:泛型约束确实返回了一个残缺的
类型
对象

让我与您分享这段代码:

public class GenericTest
{

    public class MyGenericClass<T, U, V>
        where T : System.IO.StringReader
        where U : System.IO.StringWriter
        where V : SomeOtherClass<V>
    {
    }

    public class SomeOtherClass<X>
    {
    }

    public static void Test()
    {
        Assembly a = Assembly.GetAssembly(typeof(GenericTest));
        foreach (Type t in a.GetTypes()) {
            Console.Out.WriteLine(t.FullName);
            if (t.IsGenericType) {
                Console.Out.WriteLine("\tIsGeneric!");
                foreach (Type parm in t.GetGenericArguments()) {
                    Console.Out.WriteLine("\tGeneric parameter: " + parm.Name);
                    Type[] constraints = parm.GetGenericParameterConstraints();
                    for (int i = 0; i < constraints.Length; i++) {
                        Console.Out.WriteLine("\t\t constraint " + i + ": name = " + constraints[i].Name);
                        Console.Out.WriteLine("\t\t constraint " + i + ": fullname = " + constraints[i].FullName);
                    }
                }
            }
        }

    }

}
但这不是我所期望的。我希望:

ProcessCSharpAssemblies.Program
ProcessCSharpAssemblies.GenericTest
ProcessCSharpAssemblies.GenericTest+MyGenericClass`3
    IsGeneric!
    Generic parameter: T
        constraint 0: name = StringReader
        constraint 0: fullname = System.IO.StringReader
    Generic parameter: U
        constraint 0: name = StringWriter
        constraint 0: fullname = System.IO.StringWriter
    Generic parameter: V
        constraint 0: name = SomeOtherClass`1
        constraint 0: fullname = ProcessCSharpAssemblies.GenericTest+SomeOtherClass`1
ProcessCSharpAssemblies.GenericTest+SomeOtherClass`1
    IsGeneric!
    Generic parameter: X
关键是
FullName
为引用同一程序集中定义的泛型类的约束返回
null
。这似乎很奇怪:为什么我不能为
processCSharpAssemblys.GenericTest.SomeOtherClass
获取一个有效的
Type
对象?这样一来,我就没法知道其他类是什么类了!在这个特定的示例中,
约束[i]。DeclaringType
将返回一个有效的类型对象。但我遇到了不同的情况,情况并非如此。因此,似乎我得到了一个类型对象,它被认为是不合理有效的

问:有人知道为什么会这样吗

问:如何获取类型(如
SomeOtherClass
)的FQN


问:由于各种原因,我不能使用最新版本的.Net。任何人都可以验证在最新版本的.Net中是否仍然遇到此问题吗?

此行为在所有.Net版本中都是相同的

我认为原因写在“备注”部分()的System.Type.FullName属性定义中:

如果当前类型表示泛型类型的类型参数,或基于类型参数的数组类型、指针类型或byref类型,则此属性返回null

你也可以在那里找到一些解释

如果在这种特殊情况下需要FQN(当FullName为null且约束[i].IsGenericTypeDefinition为true时),请改用此行

constraints[i].GetGenericTypeDefinition().FullName

哇,非常感谢。我还没有注意到课文的那一部分。你知道我怎样才能找到正确的类型对象吗?我编辑了原始答案,我想这解决了你的问题。注意:GetGenericTypeDefinition()只适用于“IsGenericTypeDefinition”属性为true的情况。谢谢您的回答。遗憾的是,我似乎没有遇到
GetGenericTypeDefinition()
返回true的情况,没有任何约束。你是对的,我尝试过。但是:在您的例子中(上面的示例代码),约束[i]的IsConstructedGenericType属性返回true,这似乎足以让GetGenericTypeDefinition()工作。编辑:实际上IsGenericType==真到足以让GetGenericTypeDefinition()工作并返回有效的类型objectGergely Hamos让我走上了正确的道路。(谢谢!)您似乎能够通过调用
约束[i].GetGenericTypeDefinition()
来检索正确的类型对象。据我所知,此方法将始终返回有效的
类型
对象。
constraints[i].GetGenericTypeDefinition().FullName