在C#中使用IsAssignableFrom和“is”关键字
在尝试学习Unity时 ,我一直看到下面的代码来覆盖MVC中的GetControllerInstance
:
if(!typeof(IController).IsAssignableFrom(controllerType)) { ... }
这似乎是一个基本写作的非常复杂的方式
if(controllerType is IController) { ... }
我很欣赏is
和IsAssignableFrom
之间的细微差别,即IsAssignableFrom
不包括IsAssignableFrom
转换,但是我正努力去理解这种差异在实际场景中的含义。
什么时候selectIsAssignableFrom
over is
IsAssignableFrom
is
? 在GetControllerExample
会有什么不同?
if (!typeof(IController).IsAssignableFrom(controllerType)) throw new ArgumentException(...); return _container.Resolve(controllerType) as IController;
这是不一样的。
if(controllerType is IController)
将始终计算为false
因为controllerType
始终是一个Type
,而Type
从来不是IController
。
is
运算符用于检查实例是否与给定types兼容。
IsAssignableFrom方法用于检查Type是否与给定types兼容。
typeof(IController).IsAssignableFrom(controllerType)
根据接口testingType
。 is
运算符根据接口testing实例。
is
关键字仅适用于实例,而Type.IsAssignableFrom()仅适用于types。
是的例子
string str = "hello world"; if(str is String) { //str instance is of type String }
请注意,str是一个实例,而不是types。
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的实例,它是表示Stringtypes的Type对象。
另一个明显的区别是,'是'对于testinginheritance或者接口实现是直观的,而IsAssignableFrom在它的表面上做出了任何有意义的事情。 当应用于testinginheritance或检测接口实现时,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'关键字的好处在于它可以在运行时用来testing未知的任意types,而'is'关键字(和一个genericstypes参数)需要编译时知道特定的types。