型がサブタイプであるか、オブジェクトの型であるかを確認するにはどうすればいいですか? 質問する

型がサブタイプであるか、オブジェクトの型であるかを確認するにはどうすればいいですか? 質問する

C# で型が別の型のサブクラスであるかどうかを確認するのは簡単です。

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

ただし、これは失敗します:

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

OR演算子や拡張メソッドを使用せずに、型がサブクラスであるか、または基本クラス自体のサブクラスであるかを確認する方法はありますか?

ベストアンサー1

どうやらそうではないようです。

オプションは次のとおりです:

タイプ.IsSubclassOf

すでにお分かりのとおり、2つのタイプが同じ場合はこの方法は機能しません。ここにサンプルがあります。LINQPad以下を実証するプログラム:

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

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

出力:

True
False

これは、Derivedが のサブクラスであることを示していますBaseが、 はBase(明らかに) 自身のサブクラスではありません。

タイプ.IsAssignableFrom

さて、これはあなたの特定の質問に答えますが、誤検知も与えます。Eric Lippert がコメントで指摘したように、このメソッドは確かに上記の 2 つの質問に対して結果を返しますが、おそらく望ましくない次の質問に対してTrueも結果を返します。True

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

最後のTruethere は、メソッドが尋ねられた質問に答えるだけでuint[]あれば、 がから継承するint[]か、同じ型であることを示しますが、明らかにそうではありません。

これIsAssignableFromも完全に正しいわけではありません。

isそしてas

isあなたの質問の文脈におけるおよびの「問題」asは、オブジェクトを操作していずれかの型をコード内に直接記述する必要があり、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;
}

おすすめ記事