关于C#的dynamic类型,简单演示及说明
2012-05-30 11:06
281 查看
在阅读《CLR via C# (第三版)》第132页看到dynamic这个类型,感觉挺有用的。
记录下来日后查用以及跟园友们分享,内容如下:
为了方便开发人员使用反射或者与基本组件通信,C#编译器允许将一个表达式的类型标记为 dynamic。还可以将一个表达式的结果放到一个变量中,并将变量的类型标记为dynamic。然后,可以用这个 dynamic 表达式/变量调用一个成员,比如字段、属性/索引器、方法、委托以及一元/二元/转换操作符。代码用 dynamic 表达式/变量来调用一个成员时,编译器会生成特殊的 IL 代码来描述所需的操作。这种特殊的代码成为 payload(有效载荷)。在运行时,payload 代码根据当前由 dynamic 表达式/变量引用的对象的实际类型来决定具体执行的操作。
以下代码对此进行了演示:
以上代码是经过了测试的,如果在编译过程中出现错误,可能缺少引用,比如:Microsoft.CSharp
------------------------------------------------------------
执行 Main 方法时,会得到以下输出:
M(int):10
M(string):AA
为了理解发生的事情,让我们先来研究以下 Plus 方法。这个方法将参数的类型声明为 dynamic。在方法内部,实参被作为二元+操作符的两个操作数使用。由于 arg 是 dinamic ,所以C#编译器会生成 payload 代码,以便在运行时检查 arg 的实际类型,并决定 + 操作符实际要做的事情。
第一次调用Plus时,传递的是5(一个int),所以Plus向它的调用者返回值10(也是一个int)。结果放到result变量(声明为 dynamic 类型)中。然后调用M方法,将 result 传给它。针对对 M 的调用,编译器会生成 payload 代码,以便在运行时检查传给M的值的实际类型,并决定应该调用 M 方法的哪个重载版本。在 result 包含一个 int 的前提下,调用的是获取一个 int 参数的 M 重载。
第二次调用Plus时,传递的是"A"(一个string),所以 Plus 会将 "AA" ("A"和它自己的连接的结果)传回它的调用者,后者将这个结果放到 result 变量中。然后,再次调用 M 方法,将 result 传给他。 这一次, payload 代码判断出传给 M 的值的实际类型是 String , 所以会调用获取一个 String 参数的 M 重载。
--------------------------------------
以及关于更多的 dynamic 的说明以及实现过程,这里就不做更多的介绍了,园友们可以参考《CLR via C# (第三版)》第133页,或者查下MSDN文档吧
参考:http://www.wxzzz.com/?id=95
记录下来日后查用以及跟园友们分享,内容如下:
为了方便开发人员使用反射或者与基本组件通信,C#编译器允许将一个表达式的类型标记为 dynamic。还可以将一个表达式的结果放到一个变量中,并将变量的类型标记为dynamic。然后,可以用这个 dynamic 表达式/变量调用一个成员,比如字段、属性/索引器、方法、委托以及一元/二元/转换操作符。代码用 dynamic 表达式/变量来调用一个成员时,编译器会生成特殊的 IL 代码来描述所需的操作。这种特殊的代码成为 payload(有效载荷)。在运行时,payload 代码根据当前由 dynamic 表达式/变量引用的对象的实际类型来决定具体执行的操作。
以下代码对此进行了演示:
using System; internal static class DynamicDemo { public static void Main() { for (int i = 0; i < 2; i++) { dynamic arg = (i == 0) ? (dynamic)5 : (dynamic)"A"; dynamic result = Plus(arg); M(result); } } private static dynamic Plus(dynamic arg) { return arg + arg; } private static void M(int n) { Console.WriteLine("M(int):" + n); } private static void M(string s) { Console.WriteLine("M(string):" + s); } }
以上代码是经过了测试的,如果在编译过程中出现错误,可能缺少引用,比如:Microsoft.CSharp
------------------------------------------------------------
执行 Main 方法时,会得到以下输出:
M(int):10
M(string):AA
为了理解发生的事情,让我们先来研究以下 Plus 方法。这个方法将参数的类型声明为 dynamic。在方法内部,实参被作为二元+操作符的两个操作数使用。由于 arg 是 dinamic ,所以C#编译器会生成 payload 代码,以便在运行时检查 arg 的实际类型,并决定 + 操作符实际要做的事情。
第一次调用Plus时,传递的是5(一个int),所以Plus向它的调用者返回值10(也是一个int)。结果放到result变量(声明为 dynamic 类型)中。然后调用M方法,将 result 传给它。针对对 M 的调用,编译器会生成 payload 代码,以便在运行时检查传给M的值的实际类型,并决定应该调用 M 方法的哪个重载版本。在 result 包含一个 int 的前提下,调用的是获取一个 int 参数的 M 重载。
第二次调用Plus时,传递的是"A"(一个string),所以 Plus 会将 "AA" ("A"和它自己的连接的结果)传回它的调用者,后者将这个结果放到 result 变量中。然后,再次调用 M 方法,将 result 传给他。 这一次, payload 代码判断出传给 M 的值的实际类型是 String , 所以会调用获取一个 String 参数的 M 重载。
--------------------------------------
以及关于更多的 dynamic 的说明以及实现过程,这里就不做更多的介绍了,园友们可以参考《CLR via C# (第三版)》第133页,或者查下MSDN文档吧
参考:http://www.wxzzz.com/?id=95
相关文章推荐
- 关于C#线程的简单演示
- C#简单类型转换说明
- 关于JAVA 1.5中对于泛型(参数化类型)的简单说明
- C#关于log4net(Log For Net)的使用 简单说明以及介绍
- [转]关于C#中可空类型的说明
- C#关于log4net(LogForNet)的使用简单说明以及介绍
- 关于C# 读取 写入 删除 注册表简单例子
- objective-c 多态 ——动态类型 id 的使用(与 C# 的比较说明)
- 关于C#线程,线程池和并行运算的简单使用和对比
- 关于虚函数和 Qt 的 Event 函数的简单说明
- 关于C#的类型转换
- C#WebService返回dynamic类型报错问题
- Vlc.DotNet C#音视频播放器使用说明及简单实例
- c#匿名类型最简单的例子 自动帮助我们创建类
- C# 笔记 .net与C#简单说明
- Singleton模式(Singleton创建类型)c#简单的例子
- 关于VS.Net2005中串口操作说明(C#)(SerialPort组件) (转帖)
- c#可空类型的作用说明
- C#关于手机和固定电话的简单判断
- 关于 Guid类型在数据库可为null,而C#中Guid不能为空,造成指定转换无效的错误