C#で型を判別するtypeofとis演算子

C#のクラスには継承という仕組みがあり、基底クラスを継承して新たな派生クラスを作成する事が可能です。派生クラスはアップキャストする事で基底クラスとして振る舞う事が出来るし、そこからダウンキャストして元のクラスの型へ変換する事も出来ます。

 

便利な仕組みですが、複雑なコードになると「このオブジェクトは安全に型変更できるのだろうか?」という場面に出くわす事になります。

 

 

そんな時に使うのが、typeofis 演算子です。

 

どちらも型を判別する為のものですが、挙動が少し異なります。

両者の挙動の違いを理解してうまく使い分けましょう。

typeof

typeofを使うとインスタンスを作成したクラスが何かを判別出来ます。

 

正確に言うと typeof はクラス名から型宣言(Typeクラス)を取得するものです。

一方でobjectクラスには GetType() メソッドがあり自身の型宣言が取得出来ます。

両者を比較する事でそのオブジェクトがtypeofで指定したクラスなのかを判断します。

class Base {}
class Level1 : Base{}
class Level2 : Level1{}
class Level3 : Level2{}

class Test
{
    static void Main()
    {
        Base obj = new Level2();

        bool isBase   = (typeof(Base)   == obj.GetType());     // false
        bool isLevel1 = (typeof(Level1) == obj.GetType());     // false
        bool isLevel2 = (typeof(Level2) == obj.GetType());     // true
        bool isLevel3 = (typeof(Level3) == obj.GetType());     // false
    }
}

is 演算子

is 演算子を使うとキャスト出来るかどうかをチェックできます。

 

typeofとは異なり基底クラス名で判断して場合 true が返ります。

 

class Base {}
class Level1 : Base{}
class Level2 : Level1{}
class Level3 : Level2{}

class Test
{
    static void Main()
    {
        Base obj = new Level2();

        bool isBase   = (obj is Base);       // true ←typeofと異なる
        bool isLevel1 = (obj is Level1);     // true ←typeofと異なる
        bool isLevel2 = (obj is Level2);     // true
        bool isLevel3 = (obj is Level3);     // false
    }
}