1. ホーム
  2. c#

[解決済み】ある型がサブタイプかオブジェクトの型かを確認するにはどうすればいいですか?

2022-03-25 14:02:20

質問

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

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

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

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

ある型がサブクラスであるか、あるいはベースクラスそのものであるかどうかを OR 演算子を使用するか、拡張メソッドを使用する必要がありますか?

どのように解決するのですか?

どうやら、ダメみたいです。

オプションはこちらです。

タイプ.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がコメントで指摘しているように、このメソッドは確かに True を返しますが、上記の2つの質問に対しては 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

最後の 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;
}