我正在尝试使用反射解析程序集中提供的数据。在我的场景中,我试图找出泛型参数可能具有的约束类型。在这里我遇到了一个非常奇怪的问题:泛型约束会返回一个残缺的Type
对象。
让我与您分享这段代码:
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
IsGeneric!
Generic parameter: X
但这不是我所期望的。我希望:
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
。这似乎很奇怪:为什么我没有获得Type
的有效ProcessCSharpAssemblies.GenericTest.SomeOtherClass
对象?这样我就无法分辨出SomeOtherClass
是什么类!在此特定示例中,constraints[i].DeclaringType
将返回有效的类型对象。但是我遇到了不同的情况。因此,似乎我得到了一个不被视为合理有效的类型对象。
问:如何获取SomeOtherClass
等类型的FQN?
问:由于种种原因,我无法使用最新版本的.Net。任何人都可以验证最新版本的.Net中是否仍然遇到此问题?
答案 0 :(得分:3)
此行为在所有.net版本中都是相同的。
我认为原因是在“备注”部分(https://msdn.microsoft.com/en-us/library/system.type.fullname(v=vs.110).aspx)中的System.Type.FullName属性定义中写的:
“如果当前Type表示泛型类型的类型参数,或基于类型参数的数组类型,指针类型或byref类型,则此属性返回null。”
你也可以在那里找到一些解释。
如果你想在这种特殊情况下使用FQN(当FullName为空且约束[i] .IsGenericTypeDefinition为真时),则使用此行代替
constraints[i].GetGenericTypeDefinition().FullName