2024-04-22 (月)
[C#] ある型が指定したクラスまたはインターフェイスにキャスト可能か判定する方法
通常は is や as でキャストできるか判定しますが、Type 指定でクラスやインターフェイスにキャスト可能か判定する方法です。
is と同じ結果になる方法だと思います。指定したクラスの派生または、指定したインターフェイスを実装しているか判定できます。
環境
- .NET 8.0.4 (SDK 8.0.204)
- C# 12.0
- Visual Studio 2022 Version 17.9.6
- Windows 11 Pro 22H2 22631.3447
結果
// このようなクラスがあるとします
interface IExample;
class BaseClass : IExample;
class DerivedClass : BaseClass;
void Main()
{
// 変数定義
var base1 = new BaseClass();
var derived1 = new DerivedClass();
// 変数から判定する場合は IsInstanceOfType() を使用します
// derived is BaseClass 相当
typeof(BaseClass).IsInstanceOfType(base1); // true
typeof(BaseClass).IsInstanceOfType(derived1); // true
typeof(IExample).IsInstanceOfType(derived1); // true
// Type から判定する場合は、IsAssignableFrom() を使用します
// derived is BaseClass 相当
typeof(BaseClass).IsAssignableFrom(typeof(BaseClass)); // true
typeof(BaseClass).IsAssignableFrom(typeof(DerivedClass)); // true
typeof(IExample).IsAssignableFrom(typeof(DerivedClass)); // true
// IsAssignableTo() は IsAssignableFrom() の引数指定が逆になります
// derived is BaseClass 相当
typeof(BaseClass).IsAssignableTo(typeof(BaseClass)); // true
typeof(DerivedClass).IsAssignableTo(typeof(BaseClass)); // true
typeof(DerivedClass).IsAssignableTo(typeof(IExample)); // true
}
ジェネリック型は、型引数も一致している場合に true
です。オープン ジェネリック型同士も true
です。
// List<> is List<> 相当
typeof(List<>).IsAssignableTo(typeof(List<>)); // true
typeof(List<>).IsAssignableTo(typeof(List<int>)); // false
// List<int> is List<int> 相当
typeof(List<int>).IsAssignableTo(typeof(List<int>)); // true
typeof(List<int>).IsAssignableTo(typeof(List<>)); // false
説明
以下のメソッドを使用しています。
これらの結果は、全て同じと思われます。
- 引数に
null
を指定するとfalse
が返ります。- is 演算子と同じです。
- 内部的に
Type.IsAssignableFrom(Type?)
が使用されます。
// https://github.com/dotnet/runtime/blob/v8.0.3/src/libraries/System.Private.CoreLib/src/System/Type.cs#L562
public virtual bool IsInstanceOfType([NotNullWhen(true)] object? o) => o == null ? false : IsAssignableFrom(o.GetType());
// https://github.com/dotnet/runtime/blob/v8.0.3/src/libraries/System.Private.CoreLib/src/System/Type.cs#L121-L122
public bool IsAssignableTo([NotNullWhen(true)] Type? targetType) => targetType?.IsAssignableFrom(this) ?? false;
感謝
関連記事
新着記事