C# 4,最大的创新点是拥有了动态编程语言的特性(3)

http://www.itjxue.com  2015-07-17 21:29  来源:未知  点击次数: 

  如果3级缓存中都没有命中的规则,则此动态站点所关联的调用站点绑定对象会尝试创建一个新的规则。如果创建新规则失败,则由当前编程语言(比如C#)所提供的默认调用站点绑定对象决定如何处理,通常的作法是抛出一个异常。

  当前版本的DLR第2级缓存了10条规则,第3级则缓存了100条规则。

  由于DLR自身设计了一个“规则”缓存系统,又充分利用了CLR所提供的JIT缓存(因为所有动态调用代码最终都会转换为CLR可以执行的IL指令,而CLR可以缓存这些代码),使得动态代码仅仅在第一次执行时性能较差,后续的连续调用其性能可以逼近静态代码。

  3 C# 4与动态语言的集成

  由于几乎所有的编程语言都可以使用抽象语法树来表达,因此,在理论上DLR支持无限多种编程语言间的互操作,在当前版本中,可以实现C#/Visual Basic与IronPython和IronRuby的互操作,相信很快会出现其他动态编程语言的DLR实现。

  一个有趣的地方是当前基于DLR实现的动态编程语言都以“Iron”开头,比如IronRuby和IronPython。IronPython的设计者、DLR的架构设计师Jim Hugunin曾经在微软PDC 2008大会上解释说主要是为了避免起一个“Python.NET”或“Python for .NET”之类“微软味十足”的名字,才有了“IronPython”。他强调:“Iron”系列动态语言将严格遵循动态语言自身的标准和规范,尊重这些动态语言已有的历史和积累,不会引入一些仅限于.NET平台的新语言特性,并且这些语言的.NET实现保持开源。与此同时,Jim Hugunin指出 “Iron”系列语言能很好地与.NET现有类库、编程语言和工具集成,并且能“嵌入”到.NET宿主程序中。

  (1)动态对象通讯协议

  由于各种动态编程语言之间的特性相差极大,实现各语言间的互操作是个难题。为此DLR采取了一个聪明的策略,它不去尝试设计一个“通用的类型系统”(CLR就是这么干的),而是设计了一个“通用的对象通讯协议”,规定所有需要互操作的动态对象必须实现IDynamicMetaObjectProvider接口,此接口定义了一个GetMetaObject()方法,接收一个语法树对象作为参数,向外界返回一个“动态元数据(DynamicMetaObject)”对象:

  DynamicMetaObject GetMetaObject(Expression parameter);

  DynamicMetaObject对象向外界提供了两个重要属性:Restrictions引用一组测试条件,Expression属性则引用一个语法树。这两个属性组合起来就是可供动态站点对象缓存的“规则(Rule)”。

  DLR中的“动态站点绑定对象(CallSiteBinder)”获取了DynamicMetaObject对象之后,它调用此对象所提供的各个方法创建“规则”,让“动态站点对象(CallSite)”的Target属性引用它,完成动态绑定的工作。

  (2)动态语言集成环境

  为了方便地实现静态编程语言与各种动态编程语言间的相互集成,DLR提供了一整套称为“通用寄宿(Common Hosting)”的组件,其中包容ScriptRuntime、ScriptScope等类型。

  下面我们以IronPython为例,介绍如何在C# 4开发的程序中集成动态编程语言代码。

  首先需要创建一个ScriptRuntime对象,它是一个最顶层的对象,用于在一个.NET应用程序域中“嵌入”一个特定动态语言的运行环境:

  ScriptRuntime pythonRuntime = Python.CreateRuntime();

  接着需要创建一个ScriptEngine对象,它是动态语言代码的执行引擎:

  ScriptEngine engine = pythonRuntime.GetEngine("py");

  ScriptScope对象类似于C#中的命名空间,其中可以通过定义一些变量向动态代码传入数据,比如下述代码将一个C# 创建的ExpandoObject对象传给Python代码:

  ScriptScope scope = pythonRuntime.CreateScope();

  //C#创建动态对象

  dynamic expando = new ExpandoObject();

  expando.Name = "JinXuLiang"; //动态添加一个字段

  //让IronPython接收C#创建的Expando对象

  scope.SetVariable("ExpandoObject", expando);

  string pythonCode = "print ExpandoObject.Name";

  //IronPython引擎执行Python语句

  engine.CreateScriptSourceFromString(pythonCode).Execute(scope);

  上述示例代码是直接执行Python代码。在实际开发中,更常见的是直接执行Python文件中的代码,假设有一个Calculator.py文件,其中定义了一个Add函数:

  def Add(a,b):

  return a+b

  则以下C#代码可以直接执行之:

  ScriptRuntime pythonRuntime = Python.CreateRuntime();

  dynamic pythonFile = pythonRuntime.UseFile("Calculator.py");

  Console.WriteLine(pythonFile.Add(100, 200));

  上述示例说明在DLR的支持之下,可以让静态编程语言使用动态语言所开发的库,反过来,基于DLR实现的动态编程语言也能使用为静态语言所设计的库,比如标准的.NET基类库。

  这意味着两点:

  (1)我们现在可以将“静态”和“动态”编程语言组合起来,开发出一些具有高度交互性的应用程序,使用静态编程语言搭建系统框架,使用动态编程语言实现交互性,这是一个很值得注意的应用领域。

  (2)将来会出现一些“静态”“动态”编程语言同时适用的库,向实现“无所不在的复用”目标又前进了一步。

  Visual Studio 2010为新的.NET编程语言F#提供了专门的项目模板,但没有为IronPython和IronRuby之类动态语言的开发提供支持,相信随着动态语言在.NET平台之上的应用日趋广泛,后继版本的Visual Studio会直接支持动态语言的开发。

  从C# 1.0~4.0所走过的路,可以很清晰地看到它的发展轨迹,得到这样的一个结论:

  未来的编程语言应该是多范式的,具有高度的可组合性,在一个项目或产品中组合多个编程语言、使用多种编程范式会变得越来越普遍。我们可以推断C#的后继版本将会在此条道路上越走越远……

  原文:http://blog.csdn.net/bitfan/archive/2010/08/18/5821083.aspx

(责任编辑:IT教学网)

更多

推荐编程综合文章