C# 动态语言扩展(11)

在 C# 4 开始添加 dynamic 类型。Mono C# 已经支持 C# 6.0 了。

DLR

C# 4 动态功能是 Dynamic Language Runtime (动态语言运行时,DLR)的一部分。DLR 是添加到CLR的 一系列服务,它允许添加动态语言,如 Ruby 和 Python,并是C# 具备和这些动态语言相同的某些动态功能。

IronRuby 和 IronPython 是 Ruby 和 Python 语言的开源版本,它们使用DLR。Silverlight 也可以使用 DLR。通过包含 DLR,可以给应用程序添加脚本编辑功能。脚本运行库允许给脚本传入变量和从脚本传去变量。

dynamic 类型

dynamic类型运行编写忽略编译期间的类型检查的代码。意思就是,运行之前不会检测该错误。

 public class Person
 {
     public string FirstName { get; set; }
     public string LastName { get; set; }

     public void GetFullName()
     {
         Console.WriteLine(FirstName + "   " + LastName);
     }
 }

dynamic dynamicPerson = new Person();
dynamicPerson.GetFullName("Zhao", "Lo");

运行时,会抛出 RuntimeBinderException 异常。

动态对象的类型可以任意改变。限制 不支持扩展方法,匿名函数(lambda 表达式)也不能用作动态方法调用的参数,因此LINQ不能用于动态对象。大多数LINQ调用都是扩展方法,而lambda表达式用作这些扩展方法的参数。

内部的动态操作

C# 是静态的类型化语言。那使用 dynamic 类型生成 IL (中间语言)。

class StaticClass
{
    public int IntValue = 100;
}

class DynamicClass
{
    public dynamic DynValue = 200;
}

class Program
{
    private static void Main(string[] args)
    {
        StaticClass staticClass = new StaticClass();
        DynamicClass dynamicClass = new DynamicClass();

        Console.WriteLine(staticClass.IntValue);
        Console.WriteLine(dynamicClass.DynValue);
        Console.ReadLine();
    }
}

然后用 Ildasm.exe 打开查看 IL 代码。

发现 C# 编译器做了许多工作,以支持动态类型。生成的代码中,会看到 System.Runtime.CompilerServices.CallSite 类 和 System.Runtime.CompilerServies.CallSiteBinder 类的引用。

CallSite 运行期间处理查找操作的类型。在运行期间调用动态对象时,必须找到该对象,看看其成员是否存在。CallSite会缓存这个信息。这样查找操作就不需要重复执行。

CallSite 完成了成员查找操作后,调用 CallSiteBinder() 方法。从 CallSite 提取信息,并生成表达式树,表示绑定器绑定的操作。

所以 dynamic 类型是非常有用,但是它有代价的。

包含 DLR ScriptRuntime

先从 codeplex 下载 http://dlr.codeplex.com/

假定能给应用程序添加脚本编辑功能,并给脚本传入数值和从脚本传出数值,使应用程序可以利用脚本完成工作。这些都在应用程序中包含 DLR 的 ScriptRuntime 提供的功能。目前 IronPython、InronRuby 和 JavaScript 都支持包含在应用程序中的脚本语言。

有了ScriptRuntime,就可以执行存储在文件中的代码段或完整的脚本。选择合适的语言引擎,或者让 DLR 确定使用什么引擎。脚本可以在自己的应用程序域或者在当前的应用程序域中创建。 不仅可以给脚本传入数值并从脚本中传出数值,还可以在脚本中调用在动态对象上创建的方法。

 

???????  等待下次更新整理。

 

posted @ 2016-09-13 20:55  笨重的石头  阅读(1326)  评论(0编辑  收藏  举报