Dotnet中用接口描述is和as操作符之间的区别

我们在实际工作中可能需要知道对象是否支持接口,从而可以调用相应的方法,而 Dotnet 中有 is 和 as 操作符可以满足我们判断的要求,下面我们通过接口来比较一下 Dotnet 中 is 和 as 的区别

is 操作符的形式为:表达式 is 类型。 Is 操作符在 ” 表达式 ” (必须是引用类型)可以安全的转换为 ” 类型 ” ,而不抛出异常时,结果为 true 。下面我们通过一个例子来看一看 is 的用法:

// 只在安全时转换,假设 Document 类仅仅实现 IStorable 接口,而没有实现 //ICompressible 接口,并且接口 IStorable 中有 Read(),Write() 等方法

Document doc =new Document(“test Document”);

If(Document is IStorable) //is 在此测试是否合法

{

IStorable isDoc=(IStorable) doc; // 强制转换,因为 Document 类仅仅实现 IStorable 接口,所以转换合法

isDoc.Read();

}

// 下面的转换就不合法

Document doc =new Document(“test Document”);

If(Document is ICompressible) //is 在此测试是否合法

{

ICompressible isDoc=(ICompressible) doc; // 强制转换,因为 Document 类没有实现 ICompressible 接口,所以转换不合法

isDoc.Read();

}

If 告诉我们,只有对象是正确的接口类型时才进行强制转换。这样就导致了 is 的效率不佳,为什么呢?让我们来看一段下面的 MSIL 代码:

IL_0023 : isinst ICompressible // 关键字 isinst 是 is 的 MSIL 代码,测试能否转换

IL_0028 : brfalse.s IL _0039

IL_ 002a : ldloc.0

IL_002b : castclass ICompressible // 这里又要进行测试,先测试,后转换

IL_0030 : ldloc.2

………………

所以两次的测试导致效率不佳,这时我们来看一看 as 操作符并且对它们进行比较。

As 操作符的形式是:表达式 as 类型

As 操作符将 is 操作符和转换操作结合起来,首先测试转换是否合法(即 is 测试是否转换为 true ),如是就进行转换。如转换不合法(即 is 测试是否转换为 false ), as 操作符返回 null ,我们来看一下例子:

Document doc =new Document(“test Document”);

IStorable isDoc= doc as IStorable;

If(isDoc !=null)

isDoc.Read();

else

Console.WriteLine(“IStorable not support”)

通理:

Document doc =new Document(“test Document”);

ICompressible isDoc= doc as ICompressible;

If(isDoc !=null)

isDoc.Read();

else

Console.WriteLine(“ICompressible not support”)

我们再来看一下 MSIL 代码:

IL_0023 : isinst ICompressible

IL_0028 : stloc.2

IL_ 002a : ldloc.2

IL_002b : brfalse.s IL _0034

IL_0030 : ldloc.2

这样我们一看转换只进行了一次,效率高了吧

那么这个时候我们就很清楚的就知道什么时候该用 is ,什么时该用 as 了:如果我们测试对象的目的是确定它是否属于所需类型,并且若是的话就要立即转换,这种情况下 as 操作符效率更好,但有时我们只是测试并不想立即转换,可能根本就不会转换,只是在对象实现了接口时,要将它加到一个列表中,这是 is 操作符就是一个更好的选择。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus