我正在尝试使用反射来解析程序集中提供的数据。在我的场景中,我试图找出通用参数可能具有什么样的约束。在这里我遇到了一个非常奇怪的问题:通用约束确实返回了一个残缺的 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
。这似乎很奇怪:为什么我没有获得 ProcessCSharpAssemblies.GenericTest.SomeOtherClass
的有效 Type
对象?这样我就无法判断 SomeOtherClass
是一个什么样的类!在此特定示例中,constraints[i].DeclaringType
将返回一个有效的类型对象。但我遇到过不同的情况,情况并非如此。因此,我似乎确实得到了一个不被认为合理有效的类型对象。
问:有谁知道为什么会出现这种情况吗?
问:如何获取 SomeOtherClass
等类型的 FQN?
问:由于各种原因我无法使用最新版本的.Net。谁能验证一下在最新版本的.Net 中是否仍然遇到此问题?
最佳答案
此行为在所有 .net 版本中都是相同的。
我认为原因写在“备注”部分的 System.Type.FullName 属性定义中 ( https://msdn.microsoft.com/en-us/library/system.type.fullname(v=vs.110).aspx ):
“如果当前 Type 表示泛型类型的类型参数,或者基于类型参数的数组类型、指针类型或 byref 类型,则此属性返回 null。”
您还可以在那里找到一些解释。
如果您在这种特殊情况下需要 FQN(当 FullName 为 null 且约束[i].IsGenericTypeDefinition 为 true 时),请改用此行
constraints[i].GetGenericTypeDefinition().FullName
关于c# - 如何获取 C# 中泛型约束的有效类型对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33759928/