C# 动态语言扩展(11)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 确定使用什么引擎。脚本可以在自己的应用程序域或者在当前的应用程序域中创建。 不仅可以给脚本传入数值并从脚本中传出数值,还可以在脚本中调用在动态对象上创建的方法。

 

以上是关于C# 动态语言扩展(11)的主要内容,如果未能解决你的问题,请参考以下文章

如何在扩展另一个文件的 django 模板中使用带有动态内容的 html 块片段?

扩展 C# .NET 应用程序 - 是不是构建自定义脚本语言?

C#中可以嵌入js编译器吗?这样我就好在.net中用js来写代码了

面向对象静态语言的模型

c#语言asp.net实现treeview控件读数据库动态生成树的代码

XSS:如何从 C# 中的字符串中删除 JS 片段?