オブジェクトがインターフェイスを実装しているかどうかをテストする


355

オブジェクトがC#で特定のインターフェイスを実装しているかどうかをテストする最も簡単な方法は何ですか?(Javaでのこの質問への回答 )

回答:


570
if (object is IBlah)

または

IBlah myTest = originalObject as IBlah

if (myTest != null)

85
+1 2番目の方が良いでしょう。おそらく最初の1つを後でキャストする必要が生じるため、2つのキャスト( "is"とその後の明示的なキャスト)が得られるからです。2番目のアプローチでは、1回だけキャストします。
Andrew Hare

51
@アンドリュー:+1; Julian M Bucknallによる従来のDouble-Casting AntiPatternブログ投稿へのリンクをもう一度お読みください。
Jeroen Wiert Pluimers

1
最初のケースでは、最適化でおそらく2回キャストしないでしょうか?
BuZz 2013

1
@Joreen、「as」を使用できない構造で作業している場合、「as」が返そうとするnullを保持しないため、そのリンクは1つのポイントを失います。 int?のようなクラスですが、インターフェースレベルでのみ作業している場合は問題ありません。これらは常に参照型であるためです
MikeT

46
C#6.0以降:if (object is IBlah iblah) { iblah.SomeMethod(); }
Knelis 2017年

224

isor as演算子の使用は、コンパイル時にインターフェースのタイプがわかっていて、テストするタイプのインスタンスがある場合は正しい方法です。他の誰も言及していないように思われるものは次のとおりですType.IsAssignableFrom

if( typeof(IMyInterface).IsAssignableFrom(someOtherType) )
{
}

これはによって返される配列を調べるよりもはるかにきれいでGetInterfaces、クラスでも機能するという利点があると思います。


型がIListのインスタンス化を実装しているかどうかを確認しようとしています。「typeof(IList <>)。IsAssignableFrom(someType)」を使用していますが、機能しません。
KeyboardDrummer

3
別の質問でこれを尋ねた方がよいでしょう。someTypeがリスト要素のタイプである場合、typeof(IList <>)。MakeGenericType(someType)が必要になる可能性があります。someTypeがリストタイプの場合は、Type.GetGenericArgumentsとType.GetGenericTypeDefinitionを確認する必要があります。
Andrew Kennan 2011

これをプラグインシステムでの型チェックに使用します。オブジェクトのインスタンスがまだ存在しない状況で使用できます。しかし、私はこのスタイルとロバートのスタイルの両方を使用していますが、それは私が何をしているのかに応じて、両方に賛成票を投じました。
ジェームズ

これは古いコメントですが、@ Steenreemの質問に回答するにはtypeof(IList).IsAssignableFrom(someType)、なしでを使用し<>ます。
ソース

この方法は、変換演算子とTypeConverterが関係する場合でも機能します
Harald Coppoolse '05 / 08/05

22

インスタンスの場合:

if (obj is IMyInterface) {}

クラスの場合:

typeof(MyClass).GetInterfaces()インターフェイスが含まれているかどうかを確認します。


1
if(Array.IndexOf(typeof(MyClass).GetInterfaces()、typeof(IMyInterface))!= -1){...}
Constantin

2
または:if(typeof(MyClass).GetInterfaces()。Contains(typeof(IMyInterface))){...}
Lance Fisher


16

@AndrewKennanの回答のバリエーションは、実行時に取得された型に最近使用したものです。

if (serviceType.IsInstanceOfType(service))
{
    // 'service' does implement the 'serviceType' type
}

7

この投稿は良い答えです。

public interface IMyInterface {}

public class MyType : IMyInterface {}

これは簡単なサンプルです:

typeof(IMyInterface).IsAssignableFrom(typeof(MyType))

または

typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))

3

"is"演算子を使用したテストに加えて、メソッドを装飾して、それに渡される変数が次のように特定のインターフェースを実装することを確認できます。

public static void BubbleSort<T>(ref IList<T> unsorted_list) where T : IComparable
{
     //Some bubbly sorting
}

これが実装された.Netのバージョンがわからないため、お使いのバージョンでは機能しない可能性があります。


2
.net 2.0はジェネリックを追加しました。
ロバートC.バース

これは、このスレッドでの唯一の コンパイル時チェックです。
ダスティンマローン

2

私のために働いたのは:

Assert.IsNotNull(typeof (YourClass).GetInterfaces().SingleOrDefault(i => i == typeof (ISomeInterface)));


1

最近、Andrew Kennanの回答を試してみましたが、なぜかうまくいきませんでした。代わりにこれを使用しましたが、機能しました(注:名前空間の記述が必要になる場合があります)。

if (typeof(someObject).GetInterface("MyNamespace.IMyInterface") != null)

2
あなたがこのルートに行くことになったら、私は魔法の文字列のファンではないので、少なくともこれを "MyNamespace.IMyInterface"ではなくtypeof(IMyInterface).Nameに変更します。おまけとして、それをリファクタリング証明と名付けるのに役立ちます。
greyalien007 2015年

0

使った

Assert.IsTrue(myObject is ImyInterface);

myObjectがインターフェイスImyInterfaceを実装したオブジェクトであることをテストする単体テストのテスト用です。


-1

私はメソッドに変数を渡していて、それがインターフェイスになるのかオブジェクトになるのかわからなかった状況がありました。

目標は次のとおりです。

  1. itemがインターフェイスの場合、コンストラクター呼び出しのパラメーターであるインターフェイスを使用して、そのインターフェイスに基づいてオブジェクトをインスタンス化します。
  2. アイテムがオブジェクトの場合は、呼び出しのコンストラクターがインターフェースを想定しており、コードをたたませたくないため、nullを返します。

私はこれを次のようにして達成しました:

    if(!typeof(T).IsClass)
    {
       // If your constructor needs arguments...
       object[] args = new object[] { my_constructor_param };
       return (T)Activator.CreateInstance(typeof(T), args, null);
    }
    else
       return default(T);

-12

これはうまくいくはずです:

MyInstace.GetType().GetInterfaces();

でもいいね:

if (obj is IMyInterface)

または(あまりエレガントではありません):

if (obj.GetType() == typeof(IMyInterface))

9
typeof(IMyInterface)と等しいかどうかのチェックは常に失敗します。反対票。
ジェイ・バズジ2009年

正しい。インターフェイスのインスタンスはありません。
ラウホッツ2009年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.