C# 泛型的約束圖文詳細介紹

來源:互聯網
上載者:User
本文將詳細介紹C# 泛型的約束:參考型別約束;實值型別約束;建構函式類型約束;轉換類型約束;組合約束的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧

1.參考型別約束

struct RefSample<T> where T:class 參考型別用Class表示約束,其他的參考型別為具體的約束。

表示對於的約束必須為一個類(參考型別)不能是實值型別(int,char,datatime,struct),可以是介面interface

區分,數組為參考型別,因為定義數組時需要new出一個對象。

雖然定義成 RefSample<T> 傳入的必須為參考型別 但是RefSample仍然為實值型別

2.實值型別約束

class ValSample<T> where T:struct

為參考型別,因為int,char等類型都是struct

ValSample<int>

3.建構函式類型約束

public T CreateInstance<T>() where T:new(){  return new T();}

指定的類型T必須有建構函式,CreateInstance<int>和CreateInstance<object> 都是有效。但是CreateInstance<strings>沒有建構函式。

4.轉換類型約束

一種約束允許你指定另一個類型,類型實參必須可以通過一致性、引用或裝箱轉換隱式地轉換為該類型。你還可以規定一個類型實參必須可以轉換為另一個類型實參——這稱為型別參數約束。

理解的意思:可以互換,就是我們可以通過裝箱或者強制類型轉換成目標類型的 類型都可以用於型別參數傳入。

class Sample<T> where T:Stream

有效:Sample<Stream> 這本身符合約束

無效:Sample<String> 因為String類型無法通過引用或者裝箱拆箱強制轉換成Stream、

struct Sample<T> where T:IDisposable

規定T必須為IDisposable 類型的 參考型別

有效:Sample<SqlConnection>引用轉換

無效:Sample<StringBuilder>

分析:為什麼SqlConnection 可以而StringBuilder不可以?它們都是參考型別

1.SqlConnection實現了IDisposable介面,所以可以協變

2.StringBuilder只實現了ISerializable介面,無法通過途徑轉換為IDisposable

class Sample<T> where T:IComparable<T>

因為將IComparable<T>整體當作約束,分析IComparable<T>的類型,可以用Type.IsValueType判斷,true為實值型別,false為參考型別

typeof(IComparable<T>).IsValueType 結果為false表示為參考型別

有效:Sample<int>(裝箱轉換)

無效:Sample<FileInfo>

也可以指定多種約束:

class sample<T> where T:stream,IEnumerable<string>,IComparable<int>

class Sample<T,U> where T:U

有效:Sample<Stream,IDisposable>

無效:Sample<string,IDiposable>

總結:要看傳入類參數是否可以轉換,查看規定參數和傳入類參數是否實現同一介面,如果實現則可以,否則不可以。

不可以是以下:System.Object,System.Enum,System.ValueType,System.Delegate,結構或密封類(String)

5.組合約束

對型別參數的約束有多個,注意:只能是一種類型,實值型別和參考型別不能同時存在,沒用一個類型即是參考型別,又是實值型別。

由於每一個實值型別都有一個無建構函式,此後不能再有建構函式約束

有效:

class Sample<T> where T:class,IDisposable,new()
class Sample<T,U> where T:Stream where U:IDispsable

無效:

class Sample<T> where T:class,struct (沒有任何類型即時參考型別又是實值型別的,所以為無效的)

class Sample<T> where T:Stream,class (參考型別約束應該為第一個約束,放在最前面,所以為無效的) Stream只是約束傳入參數為Stream具體類型,而class約束為參考型別,一開始我理解錯了
class Sample<T> where T:new(),Stream (new() 必須放在最後)

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 (類型形參“T”具有“struct”約束,因此“T”不能用作“U”的約束,所以為無效的)

class Sample<T,U> where T:Stream ,U:IDisposable 語法錯誤

看到網上還有這種版本也是有效我表示不理解:

class Sample<T> where T:struct,IDisapsable IDisapsable為實值型別?

class Sample<T,U> where T:class where U:struct ,T T為參考型別為何與實值型別一起約束U?

希望可以指正

以上就是C# 泛型的約束圖文詳細介紹的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.