インスタンス化されていないジェネリック型を除いて、すべてがオブジェクトから派生しているわけではありません @ Mr. Lippert's blog by Mr. Gravell's good answerで指摘されています。要件を満たす他の型を自分で見つけることをお勧めします。
それでは、この問題を解決するためにゼロから始めましょう。まず、あなたが把握しようとしている型は、コア ランタイム ライブラリにある必要がありますmscorlib.dll
。
public static partial class MartinMulderExtensions {
public static IEnumerable<Type> GetMscorlibTypes() {
return
from assembly in AppDomain.CurrentDomain.GetAssemblies()
let name=assembly.ManifestModule.Name
where 0==String.Compare("mscorlib.dll", name, true)
from type in assembly.GetTypes()
select type;
}
}
そして、型には のMakeXXXXType()
ようなメソッドがありますMakeByRefType()
。ここでは、より多くの可能性を考慮します。つまり、 type または typesを返す任意のメソッドです。任意の型の引数に関する知識がないため、メソッドは引数をゼロと見なします。
partial class MartinMulderExtensions {
public static IEnumerable<Type> GetRetrievableTypes(this Type type) {
var typesArray=(
from method in type.GetMethods()
where 0==method.GetParameters().Count()
let typeArray=
method.InvokeZeroArgumentMethodWhichReturnsTypeOrTypes(type)
where null!=typeArray
select typeArray).ToArray();
var types=
typesArray.Length>0
?typesArray.Aggregate(Enumerable.Union)
:Type.EmptyTypes;
return types.Union(new[] { type });
}
}
ただし、の実装では、非ジェネリック型InvokeZeroArgumentMethodWhichReturnsTypeOrTypes
での呼び出しなど、この種の呼び出しの無効なケースがいくつかあります。try-catchGetGenericParameterConstraints()
でこれらのケースを回避しています:
partial class MartinMulderExtensions {
public static IEnumerable<Type>
InvokeZeroArgumentMethodWhichReturnsTypeOrTypes(
this MethodInfo method, Type t
) {
try {
if(typeof(Type)==method.ReturnType) {
var type=method.Invoke(t, null) as Type;
if(null!=type)
return new[] { type };
}
if(typeof(Type[])==method.ReturnType) {
var types=method.Invoke(t, null) as Type[];
if(types.Length>0)
return types;
}
}
catch(InvalidOperationException) {
}
catch(TargetInvocationException) {
}
catch(TargetException) {
}
return Type.EmptyTypes;
}
}
そして今、目的のタイプを把握します。メソッドを段階的に構築しましょう。最初のステップは、考えられるすべてのタイプのスコープを定義することです。
partial class MartinMulderExtensions {
public static Type[] GetDesiredTypes() {
return (
from type in MartinMulderExtensions.GetMscorlibTypes()
.Select(x => x.GetRetrievableTypes())
.Aggregate(Enumerable.Union)
次に、あなたが基本的に述べたことによると:
object
ここで私の質問は次のとおりです。クラス ( IsClass == true
) であるが基本型 ( ) を持たないような「エキゾチックな」型 (ByRef 型と型以外) はありBaseType == null
ますか?
where null==type.BaseType
where type.IsClass
また、次のことも述べましたbefore answer
。
答える前に: 私はIsClass == true
! そして、タイプを使用した私の例int
は単なる例です。どんなタイプでも良かった。だからいいえ:
where !type.IsInterface
where !type.IsValueType
where typeof(void)!=type
最後のステップとして、既に回答されているものは飛ばしてメソッドを完成させましょう:
where !type.IsByRef
where !type.IsPointer
select type
).ToArray();
}
}
これで、呼び出しMartinMulderExtensions.GetDesiredTypes()
て目的の型を取得できます。
public partial class TestClass {
public static void TestMethod() {
foreach(var type in MartinMulderExtensions.GetDesiredTypes())
Console.WriteLine(type);
}
}
完全なコードの場合:
public static partial class MartinMulderExtensions {
public static IEnumerable<Type> GetMscorlibTypes() {
return
from assembly in AppDomain.CurrentDomain.GetAssemblies()
let name=assembly.ManifestModule.Name
where 0==String.Compare("mscorlib.dll", name, true)
from type in assembly.GetTypes()
select type;
}
public static IEnumerable<Type>
InvokeZeroArgumentMethodWhichReturnsTypeOrTypes(
this MethodInfo method, Type t
) {
try {
if(typeof(Type)==method.ReturnType) {
var type=method.Invoke(t, null) as Type;
if(null!=type)
return new[] { type };
}
if(typeof(Type[])==method.ReturnType) {
var types=method.Invoke(t, null) as Type[];
if(types.Length>0)
return types;
}
}
catch(InvalidOperationException) {
}
catch(TargetInvocationException) {
}
catch(TargetException) {
}
return Type.EmptyTypes;
}
public static IEnumerable<Type> GetRetrievableTypes(this Type type) {
var typesArray=(
from method in type.GetMethods()
where 0==method.GetParameters().Count()
let typeArray=
method.InvokeZeroArgumentMethodWhichReturnsTypeOrTypes(type)
where null!=typeArray
select typeArray).ToArray();
var types=
typesArray.Length>0
?typesArray.Aggregate(Enumerable.Union)
:Type.EmptyTypes;
return types.Union(new[] { type });
}
public static Type[] GetDesiredTypes() {
return (
from type in MartinMulderExtensions.GetMscorlibTypes()
.Select(x => x.GetRetrievableTypes())
.Aggregate(Enumerable.Union)
where null==type.BaseType
where type.IsClass
where !type.IsInterface
where !type.IsValueType
where typeof(void)!=type
where !type.IsByRef
where !type.IsPointer
select type
).ToArray();
}
}