此"as"非彼"as"

    因为DELPHI根深蒂固的缘故,以前看到关于"is"、"as"的资料总是一略而过,总以为它与DELPHI里是一样的东西,因为在.NET里与DELPHI一样的东西比较的多。

    直到昨天看《.NET框架程序设计》才发现原来两者之间还是有区别的,这个区别直接直接导致了.NET与DELPHI在关于类型转换上的一些建议写法。

    在DELHI下(代码乱写的,手边没有DELPHI),

type

   A = class(tobject);

   B = class(A);

var

   instA:A;

   instB:B;

begin

   instA := B.create;

   if (instA is B) then

      instB := instA as B;

end;

《Delphi* 开发人员指南》以及很多资料上都说这样的写法,由于“as”要用到RTTI信息,比较影响性能,所以大多会给出下面的这种写法

   if (instA is B) then

      instB := B(instA);

   当判断出可以转换之后直接用指针进行类型转换。

昨天看书才发现在.NET下,“is”还是那个“is”,但“as”已经不是原来那个“as”了。这里的“as”是不会抛出异常的,转换失败只是出来一个Null而已。

书不在身边,贴一段SDK文档:

The as operator is like a cast except that it yields null on conversion failure instead of raising an exception. More formally, an expression of the form:

expression as type

is equivalent to:

expression is type ? (type)expression : (type)null

except that expression is evaluated only once

也就是说,现在用实际上是“as”实际是集成了“is”与Type Cast了。

注意最后一句except that expression is evaluated only once也就是说虽然效果是等价的,但用“as”在效率上要好一点喽。

验证了一下:

 

using System;

namespace TypeCast
{
    
/// <summary>
    
/// Summary description for Class1.
    
/// </summary>

    class Class1
    
{
        
/// <summary>
        
/// The main entry point for the application.
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            
const int testcount = 500000000;
            
long tt;

            A a 
= new B();
            B b;

            tt 
= DateTime.Now.Ticks;
            
for (int i = 0;i < testcount;i++){
                
if (a is B){
                    b 
= (B)a;
                    b.x 
= 1;
                }

            }

            tt 
= DateTime.Now.Ticks - tt;
            Console.WriteLine(
"test 'is' operator:{0}",tt.ToString());

            tt 
= DateTime.Now.Ticks;
            
for (int i = 0;i < testcount;i++){
                b 
= a as B;
                
if (b != null){
                    b.x 
= 1;
                }

            }

            tt 
= DateTime.Now.Ticks - tt;
            Console.WriteLine(
"test 'as' operator:{0}",tt.ToString());

            Console.Read();

    }


        
class A{
        }


        
class B:A{
            
public int x;
        }

    }

}

结果:

test 'is' operator:115460267
test 'as' operator:68695354

的确快多了,差不多一倍。

看来还要好好看文档,

《.Net框架程序设计》这本书真不错。

原文地址:https://www.cnblogs.com/lichdr/p/75209.html