2013-03-06 47 views
1

我有一個類,如:找到一個類是否從另一個在.NET中泛型的類中派生出來?

class A<T> 
{ 

} 

我有另一個類,從上面的類派生一樣:

class B : A<X> 
{ 

} 

以上X是另一個類。

現在我可以有許多像B這樣的類,並且在這些類中泛型參數可以是其他類。

如何判斷類B的任何實例是否從A類派生?

我想:

if objB.GetType() is typeof(A<object>) //didn't work, gave false 

if objB.GetType() == typeof(A<object>) //didn't work, gave false 

if typeof(A<object>).IsAssignableFrom(obj.GetType()) //didn't work, gave false 

怎麼辦呢?

回答

1

這是有問題的;沒有IsAssignableFrom測試將在那裏工作,除非你已經知道X。你將不得不做這樣的事情:

static bool IsA(Type type) { 
    do { 
     type = type.BaseType; 
     if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(A<>)) 
      return true; 
    } while(type != null && type != typeof(object)); 
    return false; 
} 

,或者也得到了T

static bool IsA(Type type, out Type t) 
{ 
    do 
    { 
     type = type.BaseType; 
     if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(A<>)) 
     { 
      t = type.GetGenericArguments()[0]; 
      return true; 
     } 
    } while (type != null && type != typeof(object)); 
    t = null; 
    return false; 
} 
1

誤解了一下這個問題......這就是我在這種情況下會做的 - 但請注意,下面的示例只能工作1級。如果您認爲或知道其他對象將從B派生,則循環直到BaseType爲對象並使用當前類型名稱。或者,你可以密封B,使其不能從中派生出來。

public class A<T> 
    { 

    } 

    public class X 
    { 

    } 

    public class B : A<X> 
    { 


    } 


    void Test() 
    { 
     B obj = new B(); 

     if(b.GetType().BaseType.Name == "A`1") 
     { 
      Consosle.WriteLine(true); 
     } 
    } 
+0

'警告給定的表達式是永遠('A ')類型 - 即使編譯器知道這從來都不是真的 – 2013-03-06 13:50:48

+0

這是因爲示例代碼被搞亂了。 – 2013-03-06 13:54:53

+0

不,這是因爲'A '不是'A '。如果您事先知道「X」,則您的方法纔有效。請參閱「現在我可以有許多像B這樣的類,並且在這些類中泛型參數可以是其他類,如何確定像B這樣的類的任何實例是否是從A類派生的?」 – 2013-03-06 13:58:44

0

哦,這裏的一些純粹的邪惡你...利用dynamic劫持反射;這裏的關鍵點在於dynamic內置了一些基於類型的緩存,這樣就不會每次都做繁重(每類僅一次):

static void Main() 
{ 
    Console.WriteLine(IsA("abc")); // False 
    Console.WriteLine(IsA(new B())); // True 
    Console.WriteLine(IsA(123));  // False 
    Console.WriteLine(IsA(new D())); // True - where D : B 
} 
public static bool IsA(object o) 
{ 
    return (bool)EvilOnlyUseDynamicToCallThis((dynamic)o); 
} 

private static bool EvilOnlyUseDynamicToCallThis(object o) 
{ 
    return false; 
} 
private static bool EvilOnlyUseDynamicToCallThis<T>(A<T> a) 
{ 
    return true; 
} 
相關問題