且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《圣殿祭司的ASP.NET4.0专家技术手册》----2-3 C# 4.0静态基础融入动态能力

更新时间:2021-12-26 23:07:52

本节书摘来自异步社区《圣殿祭司的ASP.NET4.0专家技术手册》一书中的第2章,第3节,作者: 奚江华,译者: 武海军 , 更多章节内容可以访问云栖社区“异步社区”公众号查看。

2-3 C# 4.0静态基础融入动态能力

圣殿祭司的ASP.NET4.0专家技术手册
在了解静态与动态语言后,大家直觉上可能会以为这是二元的对立,非黑即白,不是静态语言,就是动态语言。但您是否想过静态和动态之间是可以兼具或混合的可能性?例如,静态语言为获取动态语言优点,而融入了一些动态语言的功能,然后又保持静态语言的优势,如类型安全、优化、高效率。

是的,.NET 4.0正是以这个方向去改造,在原本C#、VB静态语言基础上,加上动态语言的一些特性与优势,这样就达到以静态为主,动态为辅之目的,让C#与.NET Framework比以前更具灵活性。但本来是静态的.NET平台,要怎么能够具备动态的能力?简单来说,以下面两个要素为基础,演化.NET平台下的动态程序开发故事:

(1)在C# 4.0加入Dynamic动态类型;

(2)在.NET Framework加入新的DLR动态执行引擎。

Dynamic动态类型的运用。

C# 4.0引入了一个新的“dynamic”类型,dynamic如同int或string是一个静态类型(C# 3.0的var就只是一个关键字,而非类型),dynamic可以代表任何类型,语法如下:

dynamic name = "Kevin";
dynamic age = 30;
dynamic birthday = new DateTime(1976, 5, 28);
dynamic money = 10000.123;
…

但为什么要发明dynamic类型?这是一个很大的问题,理由有:

获取动态语言的优势,让C#静态语言也可以拥有动态语言特性;
使用dynamic类型与其他类型语言或组件互操作容易,如COM API、HTML DOM,语法会变得十分简单;
.NET Framework加入IronPython及IronRuby新语言,通过dynamic类型可以很容易与它们互动。
所以在“静态基础融入动态能力”的大前提下,并不是要从根本上打乱或放弃既有类型声明方式,而是与外来语言、COM组件或函数库互操作沟通时,通过dynamic动态类型的能力,使得程序代码变得十分精简、容易,这才是最大目的。

警告 在C#程序编写中,请不要滥用dynamic及var,声明变量时请维持明确类型声明习惯(如int、string、double等),只有对外,如IronPython或IronRuby、COM组件、函数库、LINQ、Entity Framework互操作时,才采用dynamic及var;否则程序代码难以阅读、不易事先检测语法错误,更不易得到Visual Studio开发工具支持。
dynamic可以代表任何类型,也能够当成方法参数的类型,一旦变量或对象声明为dynamic类型后,编译程序就会略过它的类型检查或语法错误,而是等到Runtime执行再评估其正确类型。虽然编译程序会略过dynamic类型或语法的检查,但并不表示编译程序对它完全无作为,编译程序会将dynamic类型变量编译成object类型变量,所以大多数情况下,dynamic类型行为模式与object类型相同。

但dynamic与object类型究竟还是有本质上的不同,否则也不必重复创造dynamic,差异点,例如,dynamic运行时会自动进行类型转换,但object则不会,如:

object o = 5;
o = o + 1;  //不合法,得明确进行类型转换o = (int)o + 1;
dynamic d = 5;
d = d + 1;  //合法,dynamic会自动类型转换

且由于dynamic类型编译时不会进行类型或某些语法检查,甚至可以调用不存在的方法,Visual Studio或编译程序也不会提示错误,而是运行时才会发生例外错误,例如:


《圣殿祭司的ASP.NET4.0专家技术手册》----2-3  C# 4.0静态基础融入动态能力

所以dynamic类型用对地方就能彰显其效果,误用则会埋下许多不良的潜在影响。而dynamic类型的应用范围除了变量外,几乎能应用在任何的场合,包括了属性、字段、索引器、参数、返回值、本机变量或类型条件约束的类型,例如:

class EmployeeInfo
{
    static dynamic EmpID;//动态类型字段

dynamic Name { get; set; }//动态类型Property
    // 动态返回类型与参数
    public dynamic getAddress(dynamic id)
    {
        //动态类型局部变量
dynamic address = "Home Address.…";
        int resultCode = 404;
        if (id is int)
        {
            return address;
        }
        else
        {
            return resultCode;
        }
    }
}

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。