2013-08-07 93 views
5

繼承我有一個通用的抽象類,這是我從派生:如何確定一個對象是否從一個抽象的通用類

abstract class SuperClass<T> 
where T : SuperDataClass 

abstract class SuperDataClass 

數據類型僅限於SuperDataClass,所以每一個具體的數據類型必須從SuperDataClass繼承。 最後,我有對超類和SuperDataClass inheriters的,例如:

class DataClassA : SuperDataClass 
class ClassA : SuperClass<DataClassA> 

class DataClassB : SuperDataClass 
class ClassB : SuperClass<DataClassB> 

如何檢查如果一個對象,例如ClassA從SuperClass繼承而不知道可能的數據類型?

我嘗試以下,這不工作:

if (testObject.GetType().IsAssignableFrom(typeof(SuperClass<SuperDataClass>))) { 
    Console.WriteLine("The test object inherits from SuperClass"); 
} 

那麼,如何if語句需要什麼樣子的?

+0

我很好奇你爲什麼想在運行期間知道這一點。你能詳細說明這個以滿足我的好奇心嗎? –

+0

嘗試使用* is *運算符http://msdn.microsoft.com/en-us/library/scekt9xw.aspx – Kimi

+0

我有一種處理多種類型的對象的方法。他們都有一個共同的抽象類,在我的例子SuperClass 派生自。所以我需要在運行期間以相同的方式處理從SuperClass 派生的所有對象。如果可能的話,我不希望爲每個具體類型單獨處理。 – sqeez3r

回答

1

遞歸

Type type2 = type; // type is your type, like typeof(ClassA) 

while (type2 != null) 
{ 
    if (type2.IsGenericType && 
     type2.GetGenericTypeDefinition() == typeof(SuperClass<>)) 
    { 
     // found 
    } 

    type2 = type2.BaseType; 
} 

請注意,如果你正在尋找一個接口,這將不起作用!

+0

但內部類型檢查丟失,必須從SuperDataClass繼承,因爲我瞭解操作。 – Matten

+0

@Matten他的問題:'ClassA從SuperClass繼承而不知道可能的數據類型?'ClassA'是'ClassA:SuperClass ' – xanatos

+0

好吧,這使得它更容易。當然,你是對的。 – Matten

1

使用IsSubclassOf功能結合泛型類型:

if (@object.GetType().IsGenericType && 
    @object.GetType().GetGenericTypeDefinition().IsSubclassOf(typeof(SuperClass<>))) { 
    Console.WriteLine("The object inherits from SuperClass"); 
} 

哪裏@object是要檢查的類型(我複製從你的問題的命名,但對象是沒有好名字,因爲它是超所有類別)。

如果您要檢查的泛型類型PARAM以及使用

if (@object.GetType().IsGenericType && 
    @object.GetType().GenericTypeArguments[0].IsSubclassOf(typeof(SuperDataClass)) && 
    @object.GetType().IsSubclassOf(typeof(Superclass<>))) 

編輯:您的最後一個註釋 - 非泛型類型推導從泛型類型:

if (@object.GetType().IsSubclassOf(typeof(Superclass<>))) 
+1

不幸的是,這對於泛型類不起作用。如果測試對象(感謝您的提示,我更改了名稱)屬於ClassA 類型,它僅適用於以下語句: if(@ object.GetType()。IsSubclassOf(typeof(SuperClass ))){ Console .WriteLine(「測試對象從SuperClass繼承」); }問題是,我也不知道數據類型。 – sqeez3r

+0

我很確定@JonSkeet可以基於強制/強制來解釋這種行爲,但我總是將它們混合在一起:) – Matten

+0

是否可以通過使用@ @ [@ [Name of]來通知尚未涉及此主題的人員用戶]'?抱歉的問題。 –

0

在這裏,你應該有一些關於預期類型的​​線索。所以在這種情況下,我會使用Type.IsSubclassOf Method

它的使用的一個例子是

Class1 myClass = new Class1(); 
DerivedC1 myDClass = new DerivedC1(); 
Type myClassType = myClass.GetType(); 
Type myDClassType = myDClass.GetType(); 

// Returns true. 
bool isSubClass = myDClassType.IsSubclassOf(myClassType)); 

我希望這有助於。

+0

爲什麼選擇投票? – MoonKnight

+0

也許是因爲你的回答原則上與馬騰相同,而你是第二。我不知道。你的回答似乎也是有效的。 –

+0

這是完全垃圾 - 我不知道上述答案(我已經投票),直到我發佈... – MoonKnight

1

顯然所有明顯的解決方案(IsSubclassOf,IsAssignableFrom,is,as)在這種情況下不起作用。於是,我就強迫的事情了一下,用這種測試的方式上來,如果一個類是SuperClass<Something>

private bool IsSuperClassOfSomeKindOfSuperDataClass(Type type) 
{ 
    if (!type.IsGenericType) 
     return false; 

    var gtd = type.GetGenericTypeDefinition(); 

    if (gtd != typeof(SuperClass<>)) 
     return false; 

    var genericParameter = type.GetGenericArguments().First(); 

    return genericParameter.IsSubclassOf(typeof(SuperDataClass)); 
} 

當然,這個測試如果一個類SuperClass<Something>,而不是是否繼承SuperClass<Something> ,所以下一個明顯的步驟將是編寫測試所有繼承層次一個合適類的函數:

private bool InheritsFromSuperClassOfSomeKindOfSuperDataClass(Type type) 
{ 
    while (type != typeof(Object)) 
    { 
     if (IsSuperClassOfSomeKindOfSuperDataClass(type)) 
      return true; 

     type = type.BaseType; 
    } 

    return false; 
} 

有了這些功能,你正在尋找的測試:

if (InheritsFromSuperClassOfSomeKindOfSuperDataClass(@object.GetType())) 
    // do stuff... 
+0

這也適用。謝謝!鑑於您的解決方案更加詳細且易於理解,xanatos的解決方案更加緊湊。 – sqeez3r

相關問題