みなさんこんにちは!ひろぽんです。
今回はInterfaceを継承しているかの判断をしたうえで、ついでにコンバートしてみるという題で書いていきたいと思います。
では早速!
まずはこんなクラスを用意する!
💡 is / as / 暗黙キャストの使い分けは別記事 C# Interface の継承判定と暗黙キャストの定石 で詳しくまとめてます。
Interfaceの準備
まずはInterfaceを二つ用意します!
public interface IVehicle
{
string MoveSound { get; }
}
public interface ICar
{
string Maker { get; }
}
でこれらを継承したクラスを用意します!
public class Subaru : IVehicle , ICar
{
public string MoveSound => "ブーブー";
public string Maker => "Subaru";
}
public class Plane : IVehicle
{
public string MoveSound => "ごぉーーーーーー";
}
SubaruクラスはIVehicle InterfaceとICar Interfaceを継承しています
が、PlaneクラスはIVehicle Interfaceしか継承していません!
Interfaceを継承しているかの判断
で、下記のようなコードを書いて、クラスがIntefaceを継承しているかを見てみましょう!
まずは下記のコードで継承しているかの判断ができます。
static void Main(string[] args)
{
var plane = new Plane();
var car = plane as ICar;
if (car != null)
{
Console.WriteLine(car.Maker);
}
else
{
Console.WriteLine("PlaneはICarを継承していません。");
}
Console.ReadLine();
}</code></pre></div>
継承していればNullにならずに変数にコンバートしたものがはいります。
が、継承していなければNullが入ります。

InterfaceからInterfaceの継承チェックもできる。
上記はクラスがInterfaceを継承しているかを見ましたが、Intefaceの型で別のInterfaceチェックもできます。
static void Main(string[] args)
{
IVehicle plane = new Plane();
var car = plane as ICar;
if (car != null)
{
Console.WriteLine(car.Maker);
}
else
{
Console.WriteLine("PlaneはICarを継承していません。");
}
Console.ReadLine();
}
}</code></pre></div>
こんな感じでvarからIVehicleにしてもチェックできますし、下記の感じでもできます。
static void Main(string[] args)
{
IVehicle subaru = new Subaru();
var car = subaru as ICar;
if (car != null)
{
Console.WriteLine(car.Maker);
}
else
{
Console.WriteLine("PlaneはICarを継承していません。");
}
Console.ReadLine();
}</code></pre></div>

Interfaceを継承していたらコンバートする
とはいえ、一度変換した後にNullチェックをするのはめんどくさい!ということで、if分の中で同時に変換できます!
static void Main(string[] args)
{
IVehicle subaru = new Subaru();
if (subaru is ICar car)
{
Console.WriteLine(car.Maker);
return;
}
Console.WriteLine("PlaneはICarを継承していません。");
Console.ReadLine();
}</code></pre></div>

Planeクラスでやるとこんな感じになります。
static void Main(string[] args)
{
IVehicle plane = new Plane();
if (plane is ICar car)
{
Console.WriteLine(car.Maker);
Console.ReadLine();
return;
}
Console.WriteLine("PlaneはICarを継承していません。");
Console.ReadLine();
}</code></pre></div>

Githubで今回のコードを公開しています!
下記リポジトリのInterfaceConvertで今回のソースを公開しています!
GitHub

GitHub - HayashiyamaHiroshi/blog-source-demo
Contribute to HayashiyamaHiroshi/blog-source-demo development by creating an account on GitHub.
💡 補足: 業務系の現場でよくハマるパターン
俺もこの Interface 継承判定、 業務でハマってきたところを3つ並べておきます。
① is と typeof() の混同
obj is IFoo は継承チェーン全部見るが、 obj.GetType() == typeof(IFoo) は厳密に一致のみ (継承先は false)。 ポリモーフィズム判定なら必ず is。 typeof 使う場面は具象クラス比較のみ。
② as 演算子の null 判定漏れ
var foo = obj as IFoo 後の null チェック忘れ → NRE。 C# 7+ なら if (obj is IFoo foo) のパターンマッチで null 判定込み・1行で済む。
③ ジェネリック制約での Interface 判定
where T : IFoo でジェネリック制約掛けると compile-time に判定。 runtime の is より型安全。 既存コード内で is を多用してる箇所はジェネリック化で改善できる場合多い。
❓ よくある質問
Q1. is と typeof() どっちが速い?
A. is の方が速い (JIT 最適化済)。 typeof().IsAssignableFrom() は reflection 経由で重い。 hot path では is 一択。
Q2. Interface の継承確認をジェネリックで書く方法は?
A. typeof(IFoo).IsAssignableFrom(typeof(T))。 ただし runtime チェックなので、 可能なら where T : IFoo の制約で compile-time に。
Q3. 複数 Interface を同時判定するには?
A. obj is IFoo && obj is IBar で AND。 OR なら obj is IFoo || obj is IBar。 C# 9+ の and/or パターンマッチも使える。
Q4. Generic 制約と is の使い分けは?
A. 静的に判定できる場面 (型が分かってる) は Generic 制約、 動的な型 (Object 引数等) は is。 制約使えるところは制約優先 (型安全 + 性能)。
Q5. Interface のキャストに失敗した時の処理は?
A. (IFoo)obj 直接キャストは InvalidCastException。 安全に処理するなら obj as IFoo で null 返却 or is パターンマッチで分岐。 詳細は 継承判定と暗黙キャストの定石 参照。
📚 関連記事
- C# Interface の継承判定と暗黙キャストの定石 — is/as/暗黙キャスト3パターン
- Interfaceの使いどころは配列ぶん回しのポリモーフィズム — Interface の基本
- C#のコールバックとデリゲートの違い — Interface vs delegate 判断
- Linq で条件カウント — Interface と Linq
- C# 例外処理の正解 — InvalidCastException の扱い
目次






コメント