1 概述:

  在早期的.NET Framework中,“Var”关键字和匿名方法开启了C#走向动态的道路,在4.0中,动态类型被添加进去。尽管C#是一个静态类型的语言,但这些额外的添加给C#带来了动态的能力。在这一章中,我们探讨一下动态类型以及它的一些使用规则,包括DynamicObject的实现和它的使用。

2 动态语言运行时(Dynamic Language Runtime)

   C# 4.0中的动态是动态语言运行时(DLR)的一部分,DLR是被添加进CLR中的一系列服务,它允许添加额外的动态语言,比如Ruby Python, 而且还允许C#具有一些这些动态语言所拥有的功能。

   .NET Framework中,DLR位于System.Dynamic命名空间,其他一些相关的类位于System.Runtime.CompilerServices命名空间。

3 动态类型(The  Dynamic Type):

   动态类型允许你的代码绕过编译时的类型检查,编译器假设你为动态对象定义的一切操作都是合法的,如果定义的操作非法,错误也只会在运行时被侦测。

   var不同的是,一个对象如果被定义为Dynamic,它可以在运行时改变类型。需要记住的是,当var被使用,对象的目标类型会被延迟,一旦类型被确定,它将不能够改变。而动态类型不仅可以改变,而且还可以改变很多次,注意这和对象的类型转换是不同的。例如:int 不能够转换成Person类型,但是如果对象是dynamic的,就可以这样做。

  dynamic dyn=100;

  Console.WriteLine(dyn.GetType());

 dyn=”This is a string”;

Console.WriteLine(dyn.GetType());

dyn=new Person(){FirstName=”Terry”,LastName=”Cheng”};

Console.WriteLine(dyn.GetType());

执行上面的代码,我们可以看出dyn对象实际上从System.Int32转换成System.String,然后转换成Person对象。如果dyn对象被申明为int 或者string,以上代码将不会被编译。

  dynamic类型的限制:1)动态对象不支持扩展方法。2)匿名方法,λ表达式不能作为动态方法调用的参数。3Linq也不适用于动态对象。

4 寄宿DLR 脚本运行时(Hosting the DLR ScriptRuntime):

  寄宿DLR脚本运行时可以让你的应用程序有添加脚本的能力,通过将参数传入或者传出脚本,可以让你的应用程序充分利用脚本所做的工作。当前可以支持的寄宿脚本语言有IronRuby,IronPython,JavaScript

  使用脚本运行时,你能够执行存储在文件中的一段或者全部的脚本,你可以选择合适的语言引擎或者让DLR来确定哪个引擎。你不仅可以从脚本里传入或者传出参数值,而且还可以在动态对象上调用写在脚本里的方法。

  脚本运行时环境的建立:1)创建ScriptRuntime 对象。2)设置合适的脚本引擎(ScriptEngine)3)创建ScriptSource4)创建ScriptScope

注:ScriptRuntime对象是脚本寄宿的开始和基础,它拥有寄宿环境的全局状态,通过静态方法CreateFromConfiguration来创建。下面是app.config文件的配置:

IronPython脚本语言为例:

<configuration>

<configSections>

<section

name="microsoft.scripting"

type="Microsoft.Scripting.Hosting.Configuration.Section,

Microsoft.Scripting,

Version=0.9.6.10,

Culture=neutral,

PublicKeyToken=null"

requirePermission="false" />

</configSections>

<microsoft.scripting>

<languages>

<language

names="IronPython;Python;py"

extensions=".py"

displayName="IronPython 2.6 Alpha"

type="IronPython.Runtime.PythonContext,

IronPython,

Version=2.6.0.1,

Culture=neutral,

PublicKeyToken=null" />

</languages>

</microsoft.scripting>

</configuration>

5 DynamicObject and ExpandoObject对象:

  1通过继承DynamicObject或者使用ExpandoObject,你可以创建自己的动态对象。不同之处是继承DynamicObject时,你需要重写相应的方法,而ExpandoObject是一个Sealed的类,可以直接使用。

2)不能够直接创建一个空的dynamic对象,动态对象必须赋值。

比如:dynamic dyn; dyn.FirstName=”Terry”将会报错。但是使用ExpandoObject可以。

  3) 如果你想在自定义的动态对象中添加属性控制,那么继承DynamicObject是首选。此外通过重写相关的方法,你能够控制自定义的对象和运行时的交互。

posted on 2011-01-20 12:46  Kv2019  阅读(296)  评论(0编辑  收藏  举报