在C#中使用IsAssignableFrom和“is”关键字

在尝试学习Unity时 ,我一直看到下面的代码来覆盖MVC中的GetControllerInstance

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

这似乎是一个基本写作的非常复杂的方式

 if(controllerType is IController) { ... } 

我很欣赏isIsAssignableFrom之间的细微差别,即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)根据接口testingTypeis运算符根据接口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。