如何檢查類型是子類型仍是對象的類型?

要檢查一個類型是不是C#中另外一個類型的子類,很簡單: ui

typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true

可是,這將失敗: this

typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false

有沒有辦法檢查類型是不是基類自己的子類OR,而無需使用OR運算符或擴展方法? spa


#1樓

typeof(BaseClass).IsAssignableFrom(unknownType);

#2樓

您應該嘗試使用Type.IsAssignableFrom.net


#3樓

顯然沒有。 code

選項以下: orm

Type.IsSubclassOf

正如您已經發現的,若是兩種類型相同,則將沒法正常工做,這是一個示例LINQPad程序,該程序演示: 對象

void Main()
{
    typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
    typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}

public class Base { }
public class Derived : Base { }

輸出: 繼承

True
False

這代表DerivedBase的子類,可是Base (顯然)不是其自身的子類。 ip

Type.IsAssignableFrom

如今,這將回答您的特定問題,但也會給您帶來誤報。 正如埃裏克·利珀特(Eric Lippert)在評論中指出的那樣,儘管該方法對於上述兩個問題的確會返回True ,但對於這些問題,也會返回True ,您可能不但願這樣作: get

void Main()
{
    typeof(Base).IsAssignableFrom(typeof(Derived)).Dump();
    typeof(Base).IsAssignableFrom(typeof(Base)).Dump();
    typeof(int[]).IsAssignableFrom(typeof(uint[])).Dump();
}

public class Base { }
public class Derived : Base { }

在這裏,您將得到如下輸出:

True
True
True

若是方法回答了所問的問題,則最後一個True表示uint[]繼承自int[]或它們是同一類型,顯然不是這種狀況。

所以IsAssignableFrom也不徹底正確。

isas

「問題」與isas你的問題的背景是,他們會要求你對對象進行操做和寫直接在代碼中的類型之一,而不是與工做Type的對象。

換句話說,它將沒法編譯:

SubClass is BaseClass
^--+---^
   |
   +-- need object reference here

也不會:

typeof(SubClass) is typeof(BaseClass)
                    ^-------+-------^
                            |
                            +-- need type name here, not Type object

也不會:

typeof(SubClass) is BaseClass
^------+-------^
       |
       +-- this returns a Type object, And "System.Type" does not
           inherit from BaseClass

結論

儘管上述方法可能知足您的需求,但對您問題的惟一正確答案(如我所見)是您將須要進行額外的檢查:

typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);

在方法中哪一個更有意義:

public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
    return potentialDescendant.IsSubclassOf(potentialBase)
           || potentialDescendant == potentialBase;
}

#4樓

我正在發佈此答案,但願有人與我分享是否以及爲何這不是一個好主意。 在個人應用程序中,我具備要檢查的Type屬性,以確保它是typeof(A)或typeof(B),其中B是從A派生的任何類。因此個人代碼是:

public class A
{
}

public class B : A
{
}

public class MyClass
{
    private Type _helperType;
    public Type HelperType
    {
        get { return _helperType; }
        set 
        {
            var testInstance = (A)Activator.CreateInstance(value);
            if (testInstance==null)
                throw new InvalidCastException("HelperType must be derived from A");
            _helperType = value;
        }
    }
}

我以爲我在這裏可能有點天真,因此歡迎任何反饋。


#5樓

若是您嘗試在Xamarin Forms PCL項目中執行此操做,則上述使用IsAssignableFrom解決方案會出現錯誤:

錯誤:「類型」不包含「 IsAssignableFrom」的定義,找不到能夠接受類型「 Type」的第一個參數的擴展方法「 IsAssignableFrom」(您是否缺乏using指令或程序集引用?)

由於IsAssignableFrom要求提供TypeInfo對象。 您能夠使用System.ReflectionGetTypeInfo()方法:

typeof(BaseClass).GetTypeInfo().IsAssignableFrom(typeof(unknownType).GetTypeInfo())

相關文章
相關標籤/搜索