nity を学習しようとしている間、MVCでGetControllerInstance
をオーバーライドする次のコードが表示され続けます。
if(!typeof(IController).IsAssignableFrom(controllerType)) { ... }
これは基本的に書くのにかなり複雑な方法です
if(controllerType is IController) { ... }
is
とIsAssignableFrom
の間には微妙な違いがあると思います。つまり、IsAssignableFrom
にはキャスト変換が含まれていませんが、実際のシナリオでこの違いの意味を理解するのに苦労しています。
IsAssignableFrom
よりもis
を選択することが重要なのはいつですか? GetControllerExample
にはどのような違いがありますか?
if (!typeof(IController).IsAssignableFrom(controllerType))
throw new ArgumentException(...);
return _container.Resolve(controllerType) as IController;
同じではありません。
if(controllerType is IController)
alwaysはfalse
と評価されます。これは、controllerType
が常にType
であり、Type
がIController
になることはありません。
is
演算子は、インスタンスが特定の型と互換性があるかどうかを確認するために使用されます。
IsAssignableFromメソッドは、Typeが特定の型と互換性があるかどうかを確認するために使用されます。
typeof(IController).IsAssignableFrom(controllerType)
は、インターフェイスに対してType
をテストします。 is
演算子は、インターフェイスに対してインスタンスをテストします。
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オブジェクトであることに注意してください。
注目すべき違いは、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」キーワード(および一般的な型パラメーター)は、特定の型のコンパイル時の知識を必要とします。