程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#泛型秘訣(1)(4)

C#泛型秘訣(1)(4)

編輯:關於C語言

這樣做的優勢在於,首先通過GenericClass<T>為數組中的項提供了類型安全。在StandardClass中可能會這樣寫代碼:

// 一般類
  StandardClass C = new StandardClass(5);
  Console.WriteLine(C);
  string s1 = "s1";
  string s2 = "s2";
  string s3 = "s3";
  int i1 = 1;
  // 在一般類中以object的形式添加項
  C.AddItem(s1);
  C.AddItem(s2);
  C.AddItem(s3);

// 在字符串數組中添加一個整數,也被允許

C.AddItem(i1);

但在GenericClass<T>中做同樣的事情將導致編譯錯誤:

  // 泛型類
  GenericClass<string> gC = new GenericClass<string>(5);
  Console.WriteLine(gC);
  string s1 = "s1";
  string s2 = "s2";
  string s3 = "s3";
  int i1 = 1;
  // 把字符串添加進泛型類.
  gC.AddItem(s1);
  gC.AddItem(s2);
  gC.AddItem(s3);
  // 嘗試在字符串實例中添加整數,將被編譯器拒絕
  // error CS1503: Argument '1': cannot convert from 'int' to 'string'
//GC.AddItem(i1);

編譯器防止它成為運行時源碼的bug,這是一件非常美妙的事情。

雖然並非顯而易見,但在StandardClass中把整數添加進object數組會導致裝箱操作,這一點可以StandardClass調用GetItem方法時的IL代碼:

Il _0170: ldloc.2
  Il _0171: ldloc.s i1 
  Il _0173: box [mscorlib]System.Int32
  Il _0178: callvirt instance int32 CSharpRecipes.Generics/StandardClass::AddItem(object)

這個裝箱操作把做為值類型的整數轉換為引用類型(object),從而可以在數組中存儲。這導致了在object數組中存儲值類型時需要增加額外的工作。

當您在運行StandardClass並從類中返回一個項時,還會產生一個問題,來看看StandardClass.GetItem如何返回一個項:

  // 存儲返回的字符串.
  string sHolder;
  // 發生錯誤CS0266:
  // Cannot implicitly convert type 'object' to 'string'…
  sHolder = (string)C.GetItem(1);

因為StandardClass.GetItem返回的是object類型,而您希望通過索引1獲得一個字符串類型,所以需要把它轉換為字符串類型。然而它有可能並非字符串-----只能確定它是一個object-----但為了賦值正確,您不得不把它轉換為更明確的類型。字符串比較特殊,所有對象都可以自行提供一個字符串描述,但當數組接收一個double類型並把它賦給一個布爾類型就會出問題。

這兩個問題在GenericClass<T>中被全部解決。無需再進行拆箱,因為GetItem所返回的是一個具體類型,編譯器會檢查返回值以強近它執行。

   string sHolder;
  int iHolder;
  // 不需要再進行轉換
  sHolder = gC.GetItem(1);
  // 嘗試把字符串變為整數.將出現
  // 錯誤CS0029: Cannot implicitly convert type 'string' to 'int'
//iHolder = gC.GetItem(1);

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