.Net 4.0 之 Dynamic 动态类型
本文主要旨在与网友分享.Net4.0的Dynamic 对Duck Type 的支持。
一、.net4.0主要新特性
.Net4.0在.Net3.5基础上新增的主要特性有:可选参数、命名参数和Dynamic。具体请阅生鱼片的这篇博文。这里我们着重讲解C#4.0的Dynamic特性,对于其他特性大家可以在VS2010内尝试一下。总之.Net在不断进步中。
二、ExpandoObject普通应用
       ExpandoObject 类,“需引用System.Dynamic命名空间” 。请看以下代码:       
 输出<< Lucy20True,这里已经类似javascript 的var obj ={}; obj.Name ='lucy'。但又不完全相同,因为不能在clr运行时动态生成属性或者方法。但至少比.NET3.5先进了。       三、Dynamic 动态类型对DuckType 的支持       1.前不久在园子里面看见了thinking的这篇博文,文中有这么一段代码:
2Customer.Name = "Lucy";
3Customer.Age = 20;
4Customer.Female = true;
5Console.WriteLine(Customer.Name + Customer.Age + Customer.Female);
6Console.ReadKey();
  
    public static T Add<T>(T t1, T t2) {
        dynamic d1 = t1;
        dynamic d2 = t2;
        return (T)(d1 + d2);
    }
}
public static void Main(string[] args){
    int i = Calculator.Add(1, 2);
    double d = Calculator.Add(1.1, 2.2);
    string s = Calculator.Add("abc", "def");
    Console.WriteLine(i + " " + d + " " + s);
}
输出:
>>3 3.3 abcdef
作者在文中指出了以上C#代码是为了通过动态类型来实现基于duck typing的泛型参数约束。
为了在C#支持Duck Type还有一个重要的.Net4.0特性有必要提及到,这也是本文重点讨论的内容。
它就是:“DynamicObject” 该类位于System.Dynamic 命名空间下。在VS2010内就可以看见该类的成员列表,截图如下:

 所属方法都是虚方法,我们可以重写这些虚方法。这里主要看TryInvokeMember()方法。这个方法VS2010给出了详细的描述。 根据VS2010注释,由于我的VS2010是英文版的,这里就不贴出英文注释了。简单介绍一下如何使用这个方法:假设我们一个类OurClass它继承了DynamicObject 这个Class。OurClass中有一个方法OurMethod()。接着在OurClass 类中 重写 TryInvokeMember这个基类虚方法。以上设置完后以后只要OurClass 的OurMethod方法一旦被调用都先执行一下重写后的 
       1、建立DynamicAnimal 类继承DynamicObject类,并且重写TryInvokeMember虚方法: 
      2、建立两个DuckType类,分别为Duck 和 Human:     3、在Console 内 建立DuckType的调用方法:
 2             if (obj && typeof obj.ourMethod === "function") {
 3                 return obj.ourMethod();
 4             }
 5             alert('未找到!');
 6             return null;
 7         }
 8 
 9         var ourObj1 = {};
10         ourObj1.Method = function () {
11             alert('111');
12         };
13 
14         var ourObj2 = {};
15         ourObj2.ourMethod = function () {
16             alert('已经找到ourMethod并且执行');
17         };
18 
19         tryInvokeMember(ourObj1);
20         tryInvokeMember(ourObj2);
    {
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            bool success = base.TryInvokeMember(binder, args, out result);
            //如果方法不存在,请将result 这个out参数赋值为null
            if (!success) 
                result = null;
            //如果这个地方返回false 将会引发异常
            return true;
        }
    }
 2     {
 3         public string Quack()
 4         {
 5             return "鸭子嘛,就Quack吧!";
 6         }
 7     }
 8  public class Human : DynamicAnimal
 9     {
10         public string Talk()
11         {
12             return "人类是用Talk,而不是Quack";
13         }
14     }
2         {
3             string result = animal.Quack();
4             return result ?? "...人类当然不会鸭叫...";
5         }
 2         {
 3             var duck = new Duck();
 4             var cow = new Human();
 5             Console.WriteLine("鸭子是Quack");
 6             Console.WriteLine(DoQuack(duck));
 7             Console.WriteLine("人类是talk");
 8             Console.WriteLine(DoQuack(cow));
 9             Console.ReadKey();
10         }

您是否对.Net4.0 Dynamic 这个动态类型有了一个新的认识呢?
最后希望本篇文章可以给您带来帮助,如有不足之处欢迎指出,谢谢!