C# 4.0 Dynamic关键字全解析(转)
两个问题是:
◆写程序时少了智能感知;
◆运行程序时速度变慢(反射)。
今天看完New features in CSharp
4.docx才恍然明白,趁着没事,把东西整理一下,希望能对暂时还不明白dynamic有什么用的朋友提供一些参考。当然,由于本人才疏学浅,不保证所有的观点都是正确的,希望大家用辩证的眼光来看这篇文章,如有错误之处,请大伙批评指正。
言归正传,dynamic关键字用于声明一个动态对象,然后通过该动态对象去调用方法或读写属性。
在使用C#
2.0或3.0的时候,如果一个对象需要在运行时才能确定,并且没有接口和基类方面的信息,那我们一般使用反射技术来调用这个未知对像的方法或属性,而C#
4.0提供的dynamic可以帮我们简化这些工作。假设我们的程序会在运行时取得一个不确定类型的对象,但这个对象一定会有个Print()方法,我们需要调用这个方法打印出一些信息,那么在C#
4.0下面,我们可以用下面的两句代码来实现这个需求。
这种解决方式比起用反射调用Print方法,应该简洁很多吧?程序员要做的就是别把方法名Print()打错,VS2010是不会为dynamic对象提供智能提示的,因为VS不知道运行时这个unknowObj会是什么东东……
到这里,应该有不少的朋友可以从这个例子上看出,当程序编译到unknowObj.Print()的时候,VS会帮我们生成反射的代码,用反射的方式去调用Print这个方法,实质上就是帮我们自动反射了。
如果能理解这一点,那也就不难理解C#为啥要搞dynamic这个既没智能感知,运行又慢的怪物出来了。
按New features in CSharp 4的说法,dymanic主要应用于下面的场景:
1、自动反射
2、COM组件互操作
3、混合编程,例如IronRuby和IronPython
4、处理Html DOM对象
如果有处理过上面这些工作的朋友们,应该不难理解了吧。
具体的内容,还请大伙自己看看New features in CSharp 4,里面说得比较详细。以上介绍C# 4.0的dynamic。
C#4.0的dynamic用法(一)——巧用反射
本文来自-拍搜学院:http://www.pasou.cn/edu/html/List18250.html
在平时做框架架构设计的时候,头疼之一的是处处得采用反射,但有了C#4.0,发现dynamic完全可以取代反射,这个功能让我有些激动,立马在VS2010将日志跟踪器框架里的第一个反射的代码升级到C#4.0,结果一点都不令人失望,代码简化了很多。
先看看用dynamic替换反射后的代码吧:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Reflection;
6 using System.IO;
7 /********************************
8 * Updated by Lihua at 03/13/2009
9 *
10 * 更新功能:
11 * 1. 升级到C#4.0,加入dynamic代替反射
12 * 2. 如果Zivsoft.Log.dll不存在,日志不输出
13 * 3. 项目编译不依赖于Zivsoft.Log.dll
14 ****************************************/
15 namespace Zivsoft.Data
16 {
17 /// <summary>
18 /// 只提供持久数据层框架里的类使用
19 /// </summary>
20 internal class Logger
21 {
22 private static Assembly _assemblyFile;
23 private static dynamic _logger;
24 static Logger()
25 {
26 var strDllFile = AppDomain.CurrentDomain.BaseDirectory + "Zivsoft.Log.dll";
27 if (File.Exists(strDllFile))
28 {
29 _assemblyFile = Assembly.LoadFile(strDllFile);
30 try
31 {
32 _logger = _assemblyFile.CreateInstance("Zivsoft.Log.Logger", false, BindingFlags.CreateInstance, null, null, null, null);
33 }
34 catch {
35 _logger = null;
36 }
37 }
38 }
39
40 public static void LogInfo(string message, params object[] args)
41 {
42 if (null != _logger)
43 {
44 _logger.LogInfo(message, args);
45 }
46 }
47
48 public static void LogWarning(string message, params object[] args)
49 {
50 if (null != _logger)
51 {
52 _logger.LogWarning(message, args);
53 }
54 }
55
56 public static void LogError(string message, params object[] args)
57 {
58 if (null != _logger)
59 {
60 _logger.LogError(message, args);
61 }
62 }
63
64 public static void LogDebug(string message, params object[] args)
65 {
66 if (null != _logger)
67 {
68 _logger.LogDebug(message, args);
69 }
70 }
71
72 public static void LogError(Exception e)
73 {
74 LogError("{0}", e);
75 }
76 }
77 }
78
以上是持久数据层调用日志跟踪器的入口代码,以前采用反射,刚被我用dynamic改了过来,经调试一点问题都没有,所以这让我欣喜,因为接下来的我的很多框架采用反射的机制将都可能被dynamic替换,比如《持久数据层框架》中的被反射的SQLServer, MySQL, Access等等数据库。
不多写了,大家仔细体会吧。