C# 4.0 动态关键字基础入门






3.30/5 (16投票s)
本简短教程将介绍 C# 4.0 中 dynamic 关键字的用法。
引言
随着 C# 4.0 的出现,我们有了一个新朋友…… dynamic。
它引用在运行时存在或不存在的对象。换句话说,它允许后期绑定。
使用代码
让我们从一个非常基本的例子开始。
示例 1:简单加法
dynamic dynVar = 10; dynVar += 10; Console.WriteLine(dynVar);
输出为:20
示例 2:简单字符串连接
dynVar += " Hello"; Console.WriteLine(dynVar);
输出为:10 Hello
但是请考虑这个
var varVariable = 10; varVariable += " Hello";
这将产生编译时错误。
无法将类型“string”隐式转换为“int”
然而,下面的代码可以正常工作
object obj = 10; obj += "Hello"; Console.WriteLine(obj);
原因:它是根据上下文推断出的特定类型,并且不会像 dynamic 那样改变类型。
示例 3
考虑以下:
dynamic dynClass = new MyClass() { IntProperty = 1 , StringProperty = "A string property" , , StringField = "A string filed" , , DecimalField = 10d };
并且
var varClass = new MyClass() { IntProperty = 1 , StringProperty = "A string property" , StringField = "A string filed" , DecimalField = 10d };
测试用例 1:显示有效属性值
Console.WriteLine(dynClass.IntProperty); //Using dynamic object Console.WriteLine(varClass.IntProperty); //using var object
一切正常,输出在每种情况下均为 1。
测试用例 2:显示无效属性值
Console.WriteLine(dynClass.InvalidProperty); //Using dynamic object
编译通过。
运行时错误:“DynamicExample.MyClass”不包含“InvalidProperty”的定义。
Console.WriteLine(varClass.InvalidProperty); //using var object
正如预期的那样,出现了编译时错误:“DynamicExample.MyClass”不包含“InvalidProperty”的定义,并且找不到接受“DynamicExample.MyClass”作为第一个参数的扩展方法“InvalidProperty”(您是否缺少 using 指令或程序集引用?)。
测试用例 3:显示有效的函数调用
Console.WriteLine(dynClass.ValidMethod()); //Using dynamic object Console.WriteLine(varClass.ValidMethod()); //using var object
正如预期的那样,一切正常,输出为 Hello。
测试用例 4:显示无效的函数调用
Console.WriteLine(dynClass.InvalidMethod()); //Using dynamic object
运行时错误:“DynamicExample.MyClass”不包含“InvalidMethod”的定义。
Console.WriteLine(varClass.InvalidMethod()); //using var object
正如预期的那样,出现了编译时错误:“DynamicExample.MyClass”不包含“InvalidMethod”的定义,并且找不到接受“DynamicExample.MyClass”作为第一个参数的扩展方法“InvalidMethod”(您是否缺少 using 指令或程序集引用?)。
示例 4:运行时调用
考虑以下两种情况:
案例 1
//Case 1: Using reflection to invoke member var type = typeof(DynamicExample.MyClass); var res1 = type.InvokeMember( "Add" , BindingFlags.InvokeMethod , null , Activator.CreateInstance(type) , new object[] { 10, 20 }); Console.WriteLine("Addition of two number using reflection= " + res1);
案例 2
//Case 2: Using Dynamic to invoke member dynamic res2 = ((dynamic)Activator.CreateInstance(typeof(DynamicExample.MyClass))).Add(10, 20); Console.WriteLine("Addition of two number using dynamic= " + res2);
输出在两种情况下均相同。
示例 5:从 C# 4.0 调用 IronPython 函数
在此,我将简要演示如何调用用 IronPython 2.6 编写的方法,并从 C# 环境动态调用该方法。
步骤 1:从 Code Plex 下载最新版本的 Iron Python。
步骤 2:安装软件。
步骤 3:在此演示中,我使用位于 Tutorial 文件夹内的“first.py”Python 文件。
该文件有两个方法:
a) Add
b) Factorial。
出于演示目的,我们只调用 Add 方法,该方法执行对作为参数传递给方法的两个数字的加法。
步骤 4:我为此演示目的使用了一个控制台应用程序。我们需要做的第一件事是添加如下所示的 dll。
步骤 5: 函数调用只需三个步骤即可完成,如下所示
static void Main(string[] args) { //Step 1: //Creating a new script runtime var ironPythonRuntime = Python.CreateRuntime(); try { //Step 2: //Load the Iron Python file/script into the memory //Should be resolve at runtime dynamic loadIPython = ironPythonRuntime.UseFile("first.py"); //Step 3: //Invoke the method and print the result Console.WriteLine( string.Format("Addition result from IronPython method for {0} and {1} is {2}",100,200, loadIPython.add(100, 200))); } catch (FileNotFoundException ex) { Console.WriteLine(ex.Message); } Console.ReadKey(true); }
第一行
var ironPythonRuntime = Python.CreateRuntime();
加载 Iron Python 库以及执行 Python 脚本所需的 DLR 代码。
第二行
dynamic loadIPython = ironPythonRuntime.UseFile("first.py");
将 Python 脚本加载到内存中。此处 dynamic 变量(loadIPython) 的重要性在于 Python 调用是在运行时解析的。
最后一行,即
Console.WriteLine(string.Format(" Addition result from IronPython method for {0} and {1} is {2}", 100,200, loadIPython.add(100, 200)) );
只是调用 Python 方法并显示结果。
步骤 6:这是输出。
示例 6:从 C# 4.0 调用 IronRuby 函数
在此,我将简要演示如何调用用 IronRuby 1.1 编写的方法,并从 C# 环境动态调用该方法。
步骤 1:从 Code Plex 下载最新版本的 Iron Ruby。
步骤 2:安装软件。
步骤 3:在此演示中,我使用的是 add.rb Ruby 文件,该文件只有一个 Add 方法,它执行对作为参数传递给方法的两个数字的加法。
步骤 4:我为此演示目的使用了一个控制台应用程序。我们需要做的第一件事是添加如下所示的 dll。
步骤 5: 函数调用只需三个步骤即可完成,如下所示
static void Main(string[] args) { //Step 1: //Creating a new script runtime var ironRubyRuntime = Ruby.CreateRuntime(); try { //Step 2: //Load the Ruby file/script into the memory //Should be resolve at runtime dynamic loadIRuby = ironRubyRuntime.UseFile(@"add.rb"); //Step 3: //Invoke the method and print the result Console.WriteLine( string.Format("Addition result from Iron Ruby method for {0} and {1} is {2}",100, 200, loadIRuby.add(100, 200)) ); } catch (FileNotFoundException ex) { Console.WriteLine(ex.Message); } Console.ReadKey(true); }
第一行
var ironRubyRuntime = Ruby.CreateRuntime();
加载 Iron Ruby 库以及执行 Python 脚本所需的 DLR 代码。
第二行
dynamic loadIRuby = ironRubyRuntime.UseFile(@"add.rb");
将 Ruby 脚本加载到内存中。此处 dynamic 变量(loadIRuby) 的重要性在于 Ruby 调用是在运行时解析的。
最后一行,即
Console.WriteLine(string.Format ("Addition result from Iron Ruby method for {0} and {1} is {2}", 100, 200, loadIRuby.add(100, 200)));
只是调用 Ruby 方法并显示结果。
步骤 6:这是输出。
参考文献
http://msdn.microsoft.com/en-us/library/dd264736.aspx结论
在这个简短的教程中,我们看到了 dynamic 关键字如何在各种情况下提供帮助。尽管如此,这个关键字也存在一些弊端,例如运行时检查,从而破坏了 C# 强类型检查的标志性优势。希望本教程能帮助您了解如何、在哪里使用 dynamic,以及如何从 C# 4.0 调用 IronPython 和 IronRuby 方法。
非常感谢您对该主题的评论,以便改进该主题。
感谢阅读本文。