程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#高級程序設計(三)——泛型基礎

C#高級程序設計(三)——泛型基礎

編輯:C#入門知識

在C#引入泛型之前,如果一個類或者一個方法想要支持多種類型,它就不得不把相應的參數或者返回值定義為object類型,這就意味著代碼在執行的過程中需要很多的轉型,並不是說你的代碼一定不要用到轉型,但是轉型確實會帶來很多潛在的問題,因為它將本該屬於編譯時的類型檢查延遲到了運行時,而且也會帶來一定的性能問題(裝箱和拆箱)。
C#2引入了泛型,包括兩種形式的泛型:泛型類型和泛型方法。下面說一下和泛型有關的一些特性:
一、泛型約束
C#泛型支持四種類型的約束,但是它們使用同樣的語法:
引用類型約束
對於引用類型的約束,泛型對象之間可以通過==和!=進行比較,但是需要注意的是,除非指定了其它約束,否則只會比較引用本身(即使引用對象類型重載了比較方法),使用轉換類型約束,重載的比較方法才會被編譯器調用。
[csharp] 
class RefSample<T> where T : class 

值類型約束
對於值類型的約束,泛型對象之間不允許使用==和!=進行比較。
[csharp] 
class ValSample<T> where T : struct 

構造函數類型約束
構造函數類型約束類型要包含無參構造函數。這樣就可以構造泛型對象實例。
[csharp] 
public T CreateInstance<T>() where T : new() 

return new T(); 

轉型類型約束
轉型類型約束允許你指明一種類型,使得參數類型必須能被隱式轉換成指明的類型。
轉換類型約束非常重要,因為你可以用泛型對象調用指明類型的方法。例如,對於T : IComparable<T>,這意味著你能直接比較兩個T類型的對象。
[csharp] 
class Sample<T> where T : Stream, 
IEnumerable<string>, 
IComparable<int> 

當幾種約束混合使用的時候,實際上還是有一些規則的,
1)沒有一個類型可以既是引用類型又是值類型,所以同時做引用類型約束和值類型約束是不允許的。
2)每一個值類型都有一個無參構造函數,所以不能同時有值類型約束和構造函數類型約束。
3)對於多個轉換類型約束,最多只能有一個類類型,而且類類型必須放在接口類型的前邊。而且每一個類型轉換約束只能出現一次。
4)不同的參數類型可以有不同的約束,它們通過各自的where來指定。
下面列出了一些合法與不合法的約束混合使用:
[csharp] 
Valid 
class Sample<T> where T : class, IDisposable, new() 
class Sample<T> where T : struct, IDisposable 
class Sample<T,U> where T : class where U : struct, T 
class Sample<T,U> where T : Stream where U : IDisposable 
Invalid 
class Sample<T> where T : class, struct 
class Sample<T> where T : Stream, class 
class Sample<T> where T : new(), Stream 
class Sample<T> where T : IDisposable, Stream 
class Sample<T> where T : XmlReader, IComparable, IComparable 
class Sample<T,U> where T : struct where U : class, T 
class Sample<T,U> where T : Stream, U : IDisposable 

二、類型推斷
C#編譯器允許在調用泛型方法的時候不用顯式指明參數類型,而是通過方法中傳遞的參數(注意不是返回值類型)進行類型推斷,注意的是這只針對泛型方法有用(對泛型類型無效),例如:
[csharp] 
static List<T> MakeList<T>(T first, T second) 
... 
List<string> list = MakeList<string>("Line 1", "Line 2"); 

對於這個泛型方法,編譯器可以根據參數的類型推斷出T,因此允許用戶無需顯式指明類型:
[csharp] view plaincopy
List<string> list = MakeList("Line 1", "Line 2"); 

三、默認值表達式
很多時候我們需要在泛型中使用默認值,C#使用default(T) 表達式返回當前泛型類型的默認值。
四、泛型中的比較
如果參數類型沒有被約束,你只能使用==/!=運算符將值和null進行比較,不能用這兩個操作符比較兩個T類型的值。
如果參數類型被約束為值類型,那麼==/!=根本就不能被應用。
如果參數類型被約束為引用類型,那麼==/!=只會比較兩者的引用。
如果參數類型被約束為為繼承自重載了==/!=的類或接口,那麼將使用重載的==/!=進行比較
例如:
[csharp] 
static bool AreReferencesEqual<T>(T first, T second) where T : class 
        { 
            return first == second; 
        } 
 www.2cto.com
string str = "World"; 
            string str1 = "Hello" + str; 
            string str2 = "Hello" + str; 
 
            Console.WriteLine(str1 == str2); 
            Console.WriteLine(AreReferencesEqual(str1, str2));  
 
Output: 
True 
False 


 

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