型がC#の別の型のサブクラスであるかどうかを確認するには、簡単です。
typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true
ただし、これは失敗します。
typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false
OR
演算子や拡張メソッドを使用せずに、型が基本クラス自体のサブクラスORであるかどうかを確認する方法はありますか?
どうやら、いや。
これが選択肢です:
is
およびas
すでにご存知のとおり、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
は(明らかに)それ自身のサブクラスではないことを示します。
さて、これはあなたの特定の質問に答えるでしょうが、それはまたあなたに誤検知を与えるでしょう。 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
最後のTrue
は、メソッドのみが質問に答えた場合、uint[]
はint[]
を継承していること、またはそれらが同じ型であることを示します。そうではありません。
そのためIsAssignableFrom
も完全に正しいわけではありません。
is
およびas
あなたの質問の文脈におけるis
とas
の「問題」は、それらをオブジェクトに作用させてコードの中に直接タイプの1つを書くことを要求し、そして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;
}
typeof(BaseClass).IsAssignableFrom(unknownType);
代わりに Type.IsAssignableFrom を使ってみてください。
Xamarin Forms PCLプロジェクトで実行しようとしている場合、IsAssignableFrom
を使用した上記の解決策ではエラーが発生します。
エラー: 'Type'は 'IsAssignableFrom'の定義を含んでおらず、 'Type'型の最初の引数を受け付ける拡張メソッド 'IsAssignableFrom'が見つかりませんでした(usingディレクティブまたはアセンブリ参照がありませんか?)
なぜならIsAssignableFrom
はTypeInfo
オブジェクトを要求するからです。 System.Reflection
からGetTypeInfo()
メソッドを使用できます。
typeof(BaseClass).GetTypeInfo().IsAssignableFrom(typeof(unknownType).GetTypeInfo())
私はこの答えを誰かが私と共有することを願って投稿しています。私のアプリケーションでは、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;
}
}
}
私はここで少し素朴であるかもしれないのでどんなフィードバックでも歓迎されるであろうように私は感じます。