.NET 4.0 之 Dynamic 動態類型

作者: ryanding  來源: 博客園  發布時間: 2010-12-21 16:19  閱讀: 1488 次  推薦: 0   原文鏈接   [收藏]  
摘要:本文主要旨在與網友分享.Net4.0的Dynamic 對Duck Type 的支持。

  一、.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
= 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
= new Human();
             Console.WriteLine(
"鴨子是Quack");
             Console.WriteLine(DoQuack(duck));
             Console.WriteLine(
"人類是talk");
             Console.WriteLine(DoQuack(cow));
             Console.ReadKey();        
}

  程序執行結果如下:

1

  您是否對.Net4.0 Dynamic 這個動態類型有了一個新的認識呢?

0
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()