• 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命名空间” 。请看以下代码:       

    复制代码
    1dynamic Customer =new ExpandoObject();
    2Customer.Name ="Lucy";
    3Customer.Age =20;
    4Customer.Female =true;
    5Console.WriteLine(Customer.Name + Customer.Age + Customer.Female);
    6Console.ReadKey();
      
    复制代码

    输出<< Lucy20True,这里已经类似javascript 的var obj ={}; obj.Name ='lucy'。但又不完全相同,因为不能在clr运行时动态生成属性或者方法。但至少比.NET3.5先进了。

        三、Dynamic 动态类型对DuckType 的支持


          1.前不久在园子里面看见了thinking的这篇博文,文中有这么一段代码:

    复制代码
    staticclass Calculator {
    publicstatic T Add<T>(T t1, T t2) {
    dynamic d1
    = t1;
    dynamic d2
    = t2;

    return (T)(d1 + d2);
    }
    }

    publicstaticvoid 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方法一旦被调用都先执行一下重写后的

       TryInvokeMember()方法。也许您会问这样到底有何用途?OK!请先看javascript这段代码片段:
    复制代码
     1 function tryInvokeMember(obj) {
    2 if (obj &&typeof obj.ourMethod ==="function") {
    3 return obj.ourMethod();
    4 }
    5 alert('未找到!');
    6 returnnull;
    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);
    复制代码
    大家读完这段js代码后应该会明白为什么我要重点讨论C#4.0中的DynamicObject了吧?真正的目的就是:在DuckType 类(鸭子) 方法(鸭子叫)执行之前,我们要判断对象的类是否是具备鸭子叫的功能?如果不具备就不应该执行,否则程序势必会抛出异常。C#中如何实现呢?步骤如下:

          1、建立DynamicAnimal 类继承DynamicObject类,并且重写TryInvokeMember虚方法:

    复制代码
    publicclass DynamicAnimal : DynamicObject
    {
    publicoverridebool TryInvokeMember(InvokeMemberBinder binder, object[] args, outobject result)
    {
    bool success =base.TryInvokeMember(binder, args, out result);

    //如果方法不存在,请将result 这个out参数赋值为null
    if (!success)
    result
    =null;

    //如果这个地方返回false 将会引发异常
    returntrue;
    }
    }
    复制代码

         2、建立两个DuckType类,分别为Duck 和 Human:

    复制代码
     1 publicclass Duck : DynamicAnimal
    2 {
    3 publicstring Quack()
    4 {
    5 return"鸭子嘛,就Quack吧!";
    6 }
    7 }
    8  publicclass Human : DynamicAnimal
    9 {
    10 publicstring Talk()
    11 {
    12 return"人类是用Talk,而不是Quack";
    13 }
    14 }
    复制代码

        3、在Console 内 建立DuckType的调用方法:

    1 publicstaticstring DoQuack(dynamic animal)
    2 {
    3 string result = animal.Quack();
    4 return result ??"...人类当然不会鸭叫...";
    5 }
       4、Console 内 Main方法调用:
    复制代码
     1 staticvoid Main(string[] args)
    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 这个动态类型有了一个新的认识呢?

  • 相关阅读:
    与开发团队高效协作的8个小技巧
    9本java程序员必读的书(附下载地址)
    NPOI导出饼图到Excel
    EF6不支持sqlite Code First解决方案
    C#程序访问底层网络
    如何自己开发软件测试工具?
    .Net mvc 根据前台参数动态绑定对象
    在SSM框架里新增一个功能
    2018-10-12 例会总结
    2018-10-11 java从入门到放弃--方法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3645743.html
Copyright © 2020-2023  润新知