zoukankan      html  css  js  c++  java
  • .NET“.NET研究” 4.0 之 Dynamic 动态类型 狼人:

      一、.NET4.0主要新特性

      .NET4.0在.Net3.5基础上新增的主要特性有:可选参数、命名参数和Dynamic。具体请阅生鱼片的这篇博文。这里我们着重讲解C#4.0的Dynamic特性,对于其他特性大家可以在VS2010内尝试一下。总之.Net在不断进步中。

      二、ExpandoObject普通应用

      ExpandoObject 类,“需引用System.Dynamic命名空间” 。请看以下代码:

    dynamic Customer = new ExpandoObject();
    Customer.Name
    = "Lucy";
    Customer.Age
    = 20;
    Customer.Female
    = true;
    Console.WriteLine(Customer.Name
    + Customer.Age + Customer.Female);
    Console.ReadKey();

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

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

      1.前不久看过这么一段代码:

    static class Calculator
    {    
    public static T Add<T>(T t1, T t2) {        
    dynamic d1
    = t1;        
    dynamic d2
    上海企业网站设计与制作pan style="color: #000000;">= 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内就可以看见该类的成员列表,截图如下:

    1

      所属方法都是虚方法,我们可以重写这些虚方法。这里主要看TryInvokeMember()方法。这个方法VS2010给出了详细的描述。  

      根据VS2010注释,由于我的VS2010是英文版的,这里就不贴出英文注释了。简单介绍一下如何使用这个方法:假设我们一个类OurClass它继承了DynamicObject 这个Class。OurClass中有一个方法OurMethod()。接着在OurClass 类中 重写 TryInvokeMember这个基类虚方法。以上设置完后以后只要OurClass 的OurMethod方法一旦被调用都先执行一下重写后的

      TryInvokeMember()方法。也许您会问这样到底有何用途?OK!请先看javascript这段代码片段:

      function tryInvokeMember(obj) {
                
    if (obj && typeof obj.ourMethod === "function") {
                     return obj.ourMethod();
                 }
                alert(
    '未找到!');
                return null;
             }
      
             var ourObj1
    = {};
             ourObj1.Method
    = function () {
                alert(
    '111');
             };

             var ourObj2

    = {};
             ourObj2.ourMethod
    = function () {
                 alert(
    '已经找到ourMethod并且执行');
             };

             tryInvokeMember(ourObj1);
             tryInvokeMember(ourObj2);

      大家读完这段js代码后应该会明白为什么我要重点讨论C#4.0中的DynamicObject了吧?真正的目的就是:在DuckType 类(鸭子) 方法(鸭子叫)执行之前,我们要判断对象的类是否是具备鸭子叫的功能?如果不具备就不应该执行,否则程序势必会抛出异常。C#中如何实现呢?步骤如下:

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

    public class DynamicAnimal : DynamicObject    {        
          
    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、建立两个DuckType类,分别为Duck 和 Human:

    public class Duck : DynamicAnimal
         {
            
    public string Quack()
             {
                return
    "鸭子嘛,就Quack吧!";
             }
         }
      
    public class Human : DynamicAnimal
         {
            
    public string Talk()
             {
                 return
    "人类是用Talk,而不是Quack";
             }
         }

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

    public static string DoQuack(dynamic animal)
             {
                
    string result = animal.Quack();
                 return result ??
    "...人类当然不会鸭叫...";
             }

      4、Console 内 Main方法调用:

    static void Main(string[] args)
             {
                 var duck
    = new Duck();
                 var cow
    =上海闵行企业网站制作"color: #000000;"> new Human();
                 Console.WriteLine(
    "鸭子是Quack");
                 Console.WriteLine(DoQua上海闵行企业网站设计与制作ck(duck));
                 Console.WriteLine(
    "人类是talk上海徐汇企业网站制作");
                 Console.WriteLine(DoQuack(cow));
                 Console.ReadKey();        
    }

      程序执行结果如下:

    1

      您是否对.Net4.0 Dynamic 这个动态类型有了一个新的认识呢?

    声明:此博有部分内容为转载,版权归原作者所有~
  • 相关阅读:
    第11条:谨慎地覆盖clone
    第10条:始终要覆盖toString
    第9条:覆盖equals时总是覆盖hashCode
    第8条:覆盖equals时请遵守通用约定
    第7条:避免使用终结方法
    第6条:消除过期的对象引用
    第5条:避免创建不必要的对象
    第4条:通过私有构造器来强化不可实例化能力
    第3条:用私有构造器或者枚举类型强化Singleton属性
    第2条:遇到多个构造器参数时要考虑用构建器
  • 原文地址:https://www.cnblogs.com/waw/p/2217020.html
Copyright © 2011-2022 走看看