简析 IsAssignableFrom 与 is 的区别

IsAssignableFrom 和 is 关键字常用于判断继承关系,特别是 IsAssignableFrom  很少人知道这个方法的存在,但它在某些场合非常有用。我们先说明结论,is 和 IsAssignableFrom的使用场景不同,is 基于实例(Instance),IsAssignableFrom是基于类型(Type)。以下篇幅主要讨论它们的区别以及使用场景。

首先,比较一下它们的官方定义

  • IsAssignableFrom(Type  c)——确定指定类型的实例是否能分配给当前类型实例。其中参数 c 为要与当前类型进行比较的类型,也就是说在类型实例化之前,判断指定的类型  c 的实例是否可以分配给当前类型的实例。
  • is —— 检查对象是否与给定类型兼容。即 is 是基于对象的,也就是类型实例化后的对象。

从定义我们可以看出,IsAssignableFrom 用于类型的实例化之前,is 用于类型的实例化之后。可能以上比较有点抽象,以下举例说明。

IsAssignableFrom 方法可以用于确定类型 c 的实例是否可以分配给当前类型的实例,方法是最有用的在处理其类型在设计时未知的对象时,适用于条件赋值,如下面的示例

using System; 
using System.Collections; 
public class Example 
{ 
  public static void Main() 
  { 
     Type t = typeof(IEnumerable); 
     Type c = typeof(Array); 
      
     IEnumerable instanceOfT; 
     int[] instanceOfC = { 1, 2, 3, 4 }; 
     if (t.IsAssignableFrom(c)) 
        instanceOfT = instanceOfC; 
 } 
}

同样地,以上示例我们还可以用于判断某个类是否实现了某个接口,如下

typeof(IFoo).IsAssignableFrom(bar.GetType()); 
typeof(IFoo).IsAssignableFrom(typeof(BarClass));

IsAssignableFrom 表示 BarClass 类型能否赋值给 IFoo 接口,它返回 true 的条件就是 BarClass 直接或间接实现了 IFoo 接口,也就是说 IsAssignableFrom 也可以用来判断继承关系。

对于 expr is type,如果满足以下条件,则返回值为 true:

  • expr 是与 type 具有相同类型的一个实例;
  • expr 是派生自 type 的类型的一个实例。 换言之,expr 结果可以向上转换为 type 的一个实例;
  • expr 具有属于 type 的一个基类的编译时类型,expr 还具有属于 type 或派生自 type 的运行时类型。 变量的编译时类型是其声明中定义的变量类型。 变量的运行时类型是分配给该变量的实例类型;
  • expr 是实现 type 接口的类型的一个实例

可以看出 is 都是基于实例的而非类型。

参考链接:

  1. https://docs.microsoft.com/zh-cn/dotnet/api/system.type.isassignablefrom
  2. https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/is
  3. https://leonax.net/p/3697/determine-if-a-class-implements-a-certain-interface/

《简析 IsAssignableFrom 与 is 的区别》的相关评论

发表评论

必填项已用 * 标记,邮箱地址不会被公开。