程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .NET,你忘記了麼?(八)—— 從dynamic到特性誤用

.NET,你忘記了麼?(八)—— 從dynamic到特性誤用

編輯:關於.NET

1. 摘要

每個程序員都想寫出漂亮的代碼,但是什麼是漂亮,這個我想每個人都有著自己的看法。 那麼我就說幾種典型的想法:

A. 寫出別人看不懂的代碼,讓別人覺得很高深。

B. 寫出簡短的代碼

C. 用最新的語言特性寫出代碼

這個我不發表評論,畢竟每個人有著自己的觀點,我也不能證明自己的就是對的。但是在 這裡,我想說一些典型的誤用。

2. 從dynamic談起

作為C#4.0的更新之一,dynamic已經越來越被推到了很多技術論壇的第一線。我看了很多 關於dynamic的講解,但是我還是我一貫的觀點。既然我們用的微軟的東西,那麼我們在使用 一個語言特性的同時,我們首先要弄清微軟為什麼要推出這門語言,不要盲目去使用。這樣 往往會適得其反。

那下面我就看大多數教程中的一個傳統代碼:

namespace ConsoleApplication1
{
   class Program
   {
     static void Main(string[] args)
     {
       dynamic p = new People("Test");
       Console.WriteLine(p.GetName());
     }
   }
   class People
   {
     private string name;
     public string GetName()
     {
       return name;
     }
     public People(string name)
     {
       this.name = name;
     }
   }
}

但是正如很多評論中的質疑的一樣,這樣的操作究竟有什麼作用?(我並不是懷疑很多作 者不懂這個,而是說這個會誤導很多人)於是很多人就會不明不白地去跟風,去亂用dynamic 。

那麼我們就在這裡說清,究竟為何dynamic。

3. dynamic和var

在說這兩個關鍵字之前,我們要先搞清楚兩個概念。什麼叫強類型語言,什麼叫弱類型語 言。

一句經典的話我想最能解釋他們的區別了:static typing when possible,dynamic typing when needed.

其實也就是說:靜態語言是在編譯時確定類型,而弱類型是在運行時確定類型。

一個簡單的例子就能看出他們的區別:

首先是使用var的情況:

接下來是dynamic:

4. 究竟為何dynamic

在國外某博客中,我記得有這樣一個說法,是說dynamic會顛覆傳統的C#編程方式,從前 說世間萬物皆為對象,那麼現在世間對象皆為dynamic。

class People
{
   private dynamic name;
   public People(dynamic name)
   {
     this.name = name;
   }
   public dynamic Introduce()
   {
     dynamic s = "Hello,I am" + name;
     return s;
   }
   public delegate dynamic Notify(dynamic argument);
}

不過,就我個人而言,並不認同這種說法,已經有很多《“深入剖析”dynamic》之類的 文章了,我就不在多寫了。總之dynamic會對效率產生很大的影響。如果這樣濫用dynamic:

A. 對程序的效率有很大影響

B. Visual Studio 強大的智能感知功能被完全廢棄了。

既然這樣,那麼我們為什麼要使用dynamic,就我的理解而言:

A. 語言的互操作,比如去調用C++的一個Com組件,我們完全可以用dynamic取代反射略顯 復雜的語法。

B. 我們都知道var只能用於變量,而無法用於屬性,而我們使用var的情況往往是因為我 們不大容易確定某一個變量(或者屬性)的類型,同樣,很可能出現一個類的屬性或者方法 返回類型不易確定返回類型的情況,這個時候,我們就可以用dynamic了。比如:

public dynamic GetAllGrilFriendsDetails()
{
   var gfDetails = from o in db.People
          where o.name = this.name
          select new
          {
            Name = o.firstName + o.lastName,
            Age = o.age,
            Address = o.address
          };
   return gfDetails;
}

為什麼我在方法內部去用 dynamic gfDetails,如果你討厭去看IL代碼細節,那麼我們只 看由於dynamic產生的反編譯C#代碼數量也許就能嚇到你了:

5. 從誤用繼續說開去

任何一種事物永遠都是雙面性的,同樣,任何一種新鮮事物的產生總是會有著他的利和他 的弊。究竟是利還是弊,其本質原因不在於他本身,而在於他周圍的環境對他的使用是利大 於弊,還是利小於弊。

任何一個C#新語言特性也是亦然。而他周圍的環境就是我們程序員。

我看到過太多太多的誤用,比如對泛型的誤用,對委托的誤用,對擴展方法的誤用。

在這裡就再談談擴展方法的誤用。

6. 何時擴展方法

我在<Javascript玩轉Prototype(二) >中提過Prototype的缺點,在這裡我只說一 點:能夠動態地添加屬性和方法固然是增加了靈活性。可是我們討論一種情況,100個人同時 來開發一個Javascript的項目,很多沒經驗的人愛上了玩轉prototype,一個人往這個類裡加 一個方法,還面向對象麼?

擴展方法也是一樣,100個開發者同時去開發一個項目,每個人都寫一個擴展方法,那麼 這個項目會亂成什麼樣大家可想而知。

那麼什麼時候該用擴展方法,我個人認為只有三種情況:

A. 你獨立負責一個組件的編寫,而這個組件需要調用其他組件中的類,而你常常需要用 到某個類中的某個他並為提供的“方法”。那麼這個時候,你可以在你的組件內特殊放置一 個類,用來容納你所需的擴展方法。

B. 一個團隊面對的一個已經封裝好的組件,但是某個方法是這個組件沒有提供的,重寫 組件實在麻煩,那好吧。擴展方法。

C. 其實這個與第二點有些相似,當你面對的是.NET Framework中提供的類庫,那麼沒辦 法,只能擴展方法。

7. 淺談泛型

C# 2.0 提出了泛型這個概念,於是越來越多的程序員愛上了泛型編程,更是據很多人反 映,有很多培訓學校中的老師教育說:用List<>取代ArrayList之類的話。

而大多數人聽從這個看法是因為培訓學校的學生並不知所以然,那麼就讓我們看看為什麼 使用泛型。

其實泛型的使用有著以下情況:

A. 保證類型安全

B. 防止裝箱拆箱的效率問題

同樣,泛型也有著一定的缺點:

A. 泛型有著一定的效率影響

B. 如果泛型過度地去嵌套,那麼便會引起代碼的膨脹問題。

那麼也就是說不滿足上述兩種情況的話,我們沒必要去使用泛型,常見的幾種誤用泛型:

A. 我見過這樣的情況:List<Object>,我實在無法猜測使用這個泛型的意義

B. 獨立開發,或是在一個方法體內,泛型的參數是一個引用類型,那麼這裡的泛型就沒 什麼太大的必要了。

8. 總結

其實誤用的根本就在於知其然而不知其所以然,在這裡,就說明情況,實在懶著浪費唇舌 去抨擊那些不值得我一抨擊的培訓學校了。

珍愛生命,遠離培訓。這是我唯一的勸告。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved