web-dev-qa-db-ja.com

C#でのIsAssignableFromおよび "is"キーワードの使用

nity を学習しようとしている間、MVCでGetControllerInstanceをオーバーライドする次のコードが表示され続けます。

if(!typeof(IController).IsAssignableFrom(controllerType)) { ... }

これは基本的に書くのにかなり複雑な方法です

if(controllerType is IController) { ... }

isIsAssignableFromの間には微妙な違いがあると思います。つまり、IsAssignableFromにはキャスト変換が含まれていませんが、実際のシナリオでこの違いの意味を理解するのに苦労しています。

IsAssignableFromよりもisを選択することが重要なのはいつですか? GetControllerExampleにはどのような違いがありますか?

if (!typeof(IController).IsAssignableFrom(controllerType))
      throw new ArgumentException(...);
return _container.Resolve(controllerType) as IController;
51

同じではありません。

if(controllerType is IController)

alwaysfalseと評価されます。これは、controllerTypeが常にTypeであり、TypeIControllerになることはありません。

is演算子は、インスタンスが特定の型と互換性があるかどうかを確認するために使用されます。

IsAssignableFromメソッドは、Typeが特定の型と互換性があるかどうかを確認するために使用されます。

80
Mark Seemann

typeof(IController).IsAssignableFrom(controllerType)は、インターフェイスに対してTypeをテストします。 is演算子は、インターフェイスに対してインスタンスをテストします。

21
Femaref

isキーワードはインスタンスにのみ適用できますが、Type.IsAssignableFrom()はタイプにのみ適用できます。

isの例

_string str = "hello world";
if(str is String)
{
    //str instance is of type String
}
_

Strはインスタンスであり、タイプではないことに注意してください。

IsAssignableFrom()の例

_string str = "hello world";
if(typeof(Object).IsAssignableFrom(str.GetType()))
{
    //instances of type String can be assigned to instances of type Object.
}

if(typeof(Object).IsAssignableFrom(typeof(string)))
{
    //instances of type String can be assigned to instances of type Object.
}
_

IsAssignableFrom()の引数はStringのインスタンスではなく、String型を表すTypeオブジェクトであることに注意してください。

16

注目すべき違いは、IsAssignableFromが一見して意味をなさないのに対して、 'is'は継承またはインターフェイス実装のテストに対して直感的に理解できることです。 Type.IsAssignableFromメソッドの名前は、継承のテストやインターフェイス実装の検出に適用すると、あいまいで混乱を招きます。これらの目的のための次のラッパーは、はるかに直感的で読みやすいアプリケーションコードになります。

    public static bool CanBeTreatedAsType(this Type CurrentType, Type TypeToCompareWith)
    {
        // Always return false if either Type is null
        if (CurrentType == null || TypeToCompareWith == null)
            return false;

        // Return the result of the assignability test
        return TypeToCompareWith.IsAssignableFrom(CurrentType);
    }

その後、次のようなより理解しやすいクライアント構文を使用できます。

    bool CanBeTreatedAs = typeof(SimpleChildClass).CanBeTreatedAsType(typeof(SimpleClass));
    CanBeTreatedAs = typeof(SimpleClass).CanBeTreatedAsType(typeof(IDisposable));

「is」キーワードの代わりにこのメソッドの利点は、未知の任意の型をテストするために実行時に使用できることですが、「is」キーワード(および一般的な型パラメーター)は、特定の型のコンパイル時の知識を必要とします。

5
Mark Jones