リフレクションを使用して、アセンブリで提供されたデータを解析しようとしています。私のシナリオでは、ジェネリックパラメーターにどのような制約があるのかを理解しようとしています。ここで、非常に奇妙な問題が発生します。一般的な制約は、機能不全の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
は、有効な型オブジェクトを返します。しかし、私はこれが当てはまらないさまざまな状況に遭遇しました。そのため、tpが妥当であると見なされない型オブジェクトを取得しているようです。
Q:なぜこれが当てはまるのか誰かが考えていますか?
Q:次のようなタイプのFQNを取得するにはどうすればよいSomeOtherClass
ですか?
Q:さまざまな理由で、最新バージョンの.Netを使用できません。誰かがこの問題が最新バージョンの.Netでまだ発生するかどうかを確認できますか?
この動作は、すべての.netバージョンで同じです。
その理由は、「備考」セクション(https://msdn.microsoft.com/en-us/library/system.type.fullname(v=vs.110)のSystem.Type.FullNameプロパティ定義に記載されていると思います。 aspx):
「現在のTypeがジェネリック型の型パラメーター、または配列型、ポインター型、または型パラメーターに基づくbyref型を表す場合、このプロパティはnullを返します。」
また、そこにいくつかの説明を見つけることができます。
この特定の場合(FullNameがnullでconstraints [i] .IsGenericTypeDefinitionがtrueの場合)にFQNが必要な場合は、代わりにこの行を使用してください
constraints[i].GetGenericTypeDefinition().FullName
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加