我们在实际工作中可能需要知道对象是否支持接口,从而可以调用相应的方法,而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操作符就是一个更好的选择。