代码改变世界

类型转换(二):是使用 is 还是 as

2011-04-24 11:22  jiejiep  阅读(270)  评论(0编辑  收藏  举报

  在上一篇类型转换(一)中,我们介绍了类型转换的基本知识,这里我们将来介绍一下使用操作符 is 和 as 来进行类型转换。

  我们先来说 is ,它判断指定的类型是否兼容于目标类型,并返回一个 bool 类型的值。例如:

  Dictionary<string, int> a = new Dictionary<string, int>( );

  
///返回 true ,因为 Dictionary<TKey,TValue> 实现了 IEnumerable 接口
  bool b = a is IEnumerable;

  
//返回 true ,所有的类都派生自 System.Object
  bool c = a is object;

  /
/返回 false ,因为 Dictionary<TKey,TValue> 与 IList 无继承关系
  bool d = a is IList;

  在代码中,如果没有给对象 a 指定引用,即当 a = null 时,无论做何种比较,is 操作都会返回 false。

  现在我们来介绍一下 is 操作符都做了哪些事:

  ① CLR 首先会获取对象 a  的实际类型

  ② CLR 会遍历对象a 的类型继承树,用每个基类型去核对指定的类型,比如这里的第一次比较(IEnumerable),如果有匹配的,则返回 true

      否则会返回 false。

  接着,我们来分析 as 操作符。as 操作符将某个对象转换为目标类型,属于强制类型转换,如 IEnumerable i = (IEnumerable) a ; 和 IEnumerable ii = a as IEnumerable; 都是强制类型转换,都执行了上面的2个步骤。不同的是,前者如果不兼容,则会抛出异常,而后者如果对象不兼容于目标类型,则会返回 null 。现在让我们来比较2段代码:

  ///代码段①
     IEnumerable e = a as IEnumerable;
if (e != null)
{
//使用e
}
     
     ///代码段②
bool f = a is IEnumerable;
if (f)
{
IEnumerable g
= (IEnumerable)a;
        ///对 g 进行操作
}

  代码段①中,CLR 首先执行步骤①②,由于 a 为 Dictionary<TKey,TValue> 类型,故兼容于 IEnumerable 接口,故 e 非空,然后 e 与 null 作比较

  代码段②中,CLR 首先执行步骤①②,由于 a 为 Dictionary<TKey,TValue> 类型,故返回 true ,在 if 语句内,将 a 转换为 IEnumerable 类型时,还要

执行步骤①②才能将 a 转换为 IEnumerable 类型,性能上代码段①更有优势。