從C# 2.0 爬向 C# 4.0—— 先說說 泛型——C# 是個優雅的語言

來源:互聯網
上載者:User
前言

   開始時學的是C#2.0而且沒有學完全。工作後,不是在忙著趕項目,就是對各種技術嘗嘗鮮,而語言的學習卻沒有什麼進步。直到半年前開始入門Python(純粹愛好,斷斷續續的學著)才發現——原來編程還可以這樣!原來代碼還可以這樣寫!

   沉溺於各種設計模式、架構、新鮮技術

   回眸一望

   忽然發現

   她

   依然如此優雅

   甚至

   更勝從前!

目標

  補完C# 2.0 3.0的新特性,然後在研究研究4.0。本章先從泛型開始溫習一下。

參考連結

  詳細讀完這些文章,你就不用看我寫的了!如有不明請往下,還是不明請留言,大家相互討論。

C#泛型簡介

Predicate泛型委派

Func(T,TResut)委託

泛型委派(C#編程指南)

走進Linq-Linq大觀園

C++ 範本和 C# 泛型間的區別

泛型

   有句經典的等式: 演算法+ 資料結構   =   程式!寫程式總會遇到一些演算法相同(處理方法相似),但資料結構不同的情況。難道就為了把int 改成 double 、Struct或Class A ,而把代碼再打一遍嗎?

  你很勤快,不在乎多敲一次代碼?不,程式員應該很懶!讓機器幫我們去做吧,於是我們有了泛型——Class Stack<T>。

C#2.0 引入了泛型它類似於C++的模板(都是C 一家親嘛,另外推薦一篇利用C++模板來列印質數的博文,它的厲害之處在於利用c++模板的特性,在編譯時間計算出質數而不是運行時 ——質數列印),但是在實現和功能方面還是存在差異的。我們可以這樣定義泛型

 1  /// <summary>
2 /// 在類上定義
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5   public class Stack<T>
6 {
7 public void Push(T value)
8 { }
9 }
10
11 /// <summary>
12 /// 在方法裡
13 /// </summary>
14   public class Stack
15 {
16 public void Push<T>(T value)
17 { }
18 public T Pop<T>(T value1, T value2) { return value1; }
19 }
20 /// <summary>
21 /// 錯誤案例,因為 預留位置 還沒聲明,就使用了。
22 /// </summary>
23   //public class StackT
24 //{
25 // public void Push(T value)
26 // { }
27 //}
28
29 //委託
30   public delegate TResult Add<T,TResult>(T value);

  其實T 就是一個預留位置(為啥是T?當然你也可以是V、R、Y,這得從它哥哥說起),個人認為把泛型裡的T理解為預留位置是最直接的。先聲明<T> ,然後就可以在該泛型裡,直接使用這個預留位置T了。編譯器會根據 調用泛型時指定的預留位置T的類型,來替換 或推斷出對應的類型。

//聲明 
public class Stack<T>
{
//在 Stack 的範圍裡 可以調用。
public void Push(T value)
{ }

public void Pop<V>(statck<V> s, params V[] p){}
}

在使用 class Stack  時 必須指定T  預留位置是什麼,編譯器就能推斷出 Push(T)的類型了。而Pop 裡的V是另一個預留位置,在使用時需要指定。

  Stack<int> stack = new Stack<int>();
stack.Pop<string>("nihao ", "sdfsdf", "sdfsdf", "sdfsdfvwevwwve");

其實這個例子除了表明一些文法外,沒什麼意義。

泛型委派

   委託也可以定義泛型,將參數一般化。在.net 3.5 裡為我們定義了幾個常見的泛型委派Predicate<> Func<>  Action<> 等幾個泛型。 有了這幾個常用的委託我們寫起代碼來就更加方便了。

View Code

  class Program
{
static void Main(string[] args)
{

Func<string, string> test1 = IsTooLong;
Func<string, string> test2 = delegate(string str)
{
if (str.Length > 10)
{
return "Too long";
}
else
{
return "ok";
}
};
Func<string, string> test3 = (str) => str.Length > 10 ? "Too long" : "ok";


Console.WriteLine(test3("sodiinbgweoeinbowevw"));




Console.Read();
}

static string IsTooLong(String value)
{
if (value.Length > 10)
{
return "Too long";
}
else
{
return "ok";
}
}


}

代碼使用 Func<> 定義了3個有傳回值的委託, 然後再將委託的運行結果輸出,如果字串的長度大於10 則輸出“Too Long”。

test1裡 也可以寫成“test1 = new Func<string, string>(IsTooLong);” ,但是直接賦予 =IsTooLong更簡潔不是嗎? 這得歸功於編譯器的委託推理,它能夠推斷出我們分配到委託的類型,並驗證該方法是否與簽名相匹配。

test2 用到了 匿名方法

test3 則是使用了lambda 運算式,這個是不是更簡潔。

後記

  這裡只簡單的介紹一下泛型,詳細的資訊可以查看參考連結。把T 理解為預留位置 就好,編譯器會幫我們替換它的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.