2010-12-30 16 views
6

オブジェクトがあるとしたら、そのオブジェクトが特定のジェネリッククラスから派生しているかどうかをどのように知ることができますか?たとえば、オブジェクトが特定の汎用クラスから派生しているかどうかをどのように知ることができますか?

public class GenericClass<T> 
{ 
}  

public bool IsDeriveFrom(object o) 
{ 
    return o.GetType().IsSubclassOf(typeof(GenericClass)); //will throw exception here 
} 

上記のコードは例外をスローすることに注意してください。タイプ・パラメーターを指定しないで汎用クラスのタイプがないため、汎用クラスのタイプを直接検索することはできません。

あなたはこのような何かをすべき

答えて

2

public class GenericClass<T> 
    { 
    } 

    public class GenericClassInherited<T> : GenericClass<T> 
    { 
    } 


    public static bool IsDeriveFrom(object o) 
    { 
     return o.GetType().BaseType.GetGenericTypeDefinition() == typeof(GenericClass<>); 
    } 

例:

static void Main(string[] args) 
    { 
     var generic = new GenericClassInherited<int>(); 
     var isTrue = IsDeriveFrom(generic); 
    } 
+1

:フー:GenericFoo 'と上そして。 – jason

+0

私は知っていますが、とにかく上の例でうまくいきます。 @Edisonは自分自身を処理する例外を追加することができます。単なるアイデアです。 –

+0

私はサンプルコードを試して、いくつかの例外処理コードを追加しました。完璧な作業です。他の回答もここに私に役立つ情報がありましたが、なぜ私はそれらの役に立つ答えに投票できないのか分かりません。 –

2
bool IsDerivedFrom(Type type, Type genericBaseTypeDefinition) { 
    Contract.Requires(type != null); 
    Contract.Requires(genericBaseTypeDefinition != null); 
    Contract.Requires(genericBaseTypeDefinition.IsGenericBaseTypeDefinition); 
    Type baseType = type.BaseType; 
    if (baseType == null) { 
     return false; 
    } 

    if (baseType.IsGenericType) { 
     Type generic = baseType.GetGenericTypeDefinition(); 
     if (generic == null) { 
      return false; 
     } 
     return generic == genericBaseTypeDefinition; 
    } 

    return IsDerivedFrom(baseType, genericBaseTypeDefinition); 
} 

使用法:

bool derived = IsDerivedFrom(typeof(Foo), typeof(GenericFoo<>)); 

これらのテストに合格:

0123を
class GenericFoo<T> { } 
class DerivedGenericFoo<T> : GenericFoo<T> { } 
class Foo : GenericFoo<int> { } 
class Bar : Foo { } 
class Animal { } 

[Fact] 
public void DerivedGenericFoo_derives_from_open_GenericFoo() { 
    Assert.Equal(
     true, 
     IsDerivedFrom(
      typeof(DerivedGenericFoo<int>), 
      typeof(GenericFoo<>) 
     ) 
    ); 
} 

[Fact] 
public void Foo_derives_from_open_GenericFoo() { 
    Assert.Equal(true, IsDerivedFrom(typeof(Foo), typeof(GenericFoo<>))); 
} 

[Fact] 
public void Bar_derives_from_open_GenericFoo() { 
    Assert.Equal(true, IsDerivedFrom(typeof(Bar), typeof(GenericFoo<>))); 
} 

[Fact] 
public void Animal_does_not_derive_from_open_GenericFoo() { 
    Assert.Equal(false, IsDerivedFrom(typeof(Animal), typeof(GenericFoo<>))); 
} 
1

キーはType.GetGenericTypeDefinitionです。ここでは完全な例です:

基本型が存在しない、またはそこにジェネリック型定義はないが、それが失敗したときに `バー時に非常に多くの例外をスローすることができます
class Generic<T> { } 

class Derived<T> : Generic<T> { } 
class NonDerived<T> { } 

class Program 
{ 
    static bool IsDerivedFromGenericT(Type type) 
    { 
     if (!type.IsGenericType) 
      return false; 
     if (type.GetGenericTypeDefinition() == typeof(Generic<>)) 
      return true; 
     if (type.BaseType == null) 
      return false; 
     return IsDerivedFromGenericT(type.BaseType); 
    } 

    static void Main(string[] args) 
    { 
     var b1 = IsDerivedFromGenericT(new Derived<int>().GetType()); // true 
     var b2 = IsDerivedFromGenericT(new Derived<string>().GetType()); // true 
     var b3 = IsDerivedFromGenericT(new NonDerived<string>().GetType()); // false 
    } 
} 
+1

間違いなく、これはもっと良い例です –

関連する問題