用人類自然的語言說泛型

2021-04-13 11:35:37 字數 4292 閱讀 3457

泛型

一、什麼是泛型?

通過泛型可以定義型別安全類,而不會損害型別安全、效能或工作效率

二、例項化泛型

1、可以使用任何型別來宣告和例項化

2、申明和例項話都必須用乙個特定的型別來代替一般型別t

3、例子:

//原來寫法

public   class   stack

public   object   pop() }

stack   stack   =   new   stack();

stack.push(1);

int   number   =   (int)stack.pop();

//有了泛型後

public   class   stack

public   t   pop() }

stack stack   =   new   stack ();

stack.push(1);

int   number   =   (int)stack.pop();

三:泛型的好處

1、一次性的開發、測試和部署**,通過任何型別來重用它

2、編譯器支援和型別安全

3、不會強行對值型別進行裝箱和取消裝箱,或者對引用型別進行向下強制型別轉換,所以效能得到顯著提高。

注:值型別大概可以提高200%,引用型別大概為100%

四:多個泛型

1、單個型別可以定義多個泛型

五:泛型別名

1、在檔案頭部使用using   為特定型別取別名,別名作用範圍是整個檔案

2、例子

using   list   =   linkedlist ;

class   listclient }

五:泛型約束

(1)、派生約束

如: public   class   linkedlist where   k:icomparable }

注意:

1、所有的派生約束必須放在類的實際派生列表之後

如:public   class   linkedlist :ienumerable where   k:icomparable

2、乙個泛型引數上可以約束多個介面(用逗號分隔)

public   class   linkedlist where   k:icomparable ,iconvertible

3、在乙個約束中最多只能使用乙個基類

4、約束的基類不能是密封類或靜態類

5、不能將system.delegate或system.array約束為基類

6、可以同時約束乙個基類以及乙個或多個介面,但是該基類必須首先出現在派生約束列表中。

7、c#允許你將另乙個泛型引數指定為約束

public   class   myclass where   t:u

8、可以自己定義基類或介面進行泛型約束

9、自定義的介面或基類必須與泛型具有一致的可見性

(2)、建構函式約束

如: class   node   where   t:new()

注意:

1、可以將建構函式的約束和派生約束結合起來,前提是建構函式的約束出現在約束列表中的最後

(3)、引用/值型別約束

1、可以使用struct約束將泛型引數約束為值型別(如int、bool、enum),或任何自定義結構

2、同樣可以使用class約束將泛型引數約束為引用型別

3、不能將引用/值型別約束與基類約束一起使用,因為基類約束涉及到類

4、不能使用結構和預設建構函式約束,因為預設建構函式約束也涉及到類

5、雖然您可以使用類和預設建構函式約束,但是這樣做沒有任何價值

6、可以將引用/值型別約束與介面約束組合起來,前提是引用/值型別約束出現在約束列表的開頭

六:泛型和強制型別轉換

1、c#編譯器只允許將泛型引數隱式轉換到object或約束指定的型別

如: inte***ce   is

class   baseclass

class   myclass where   t:baseclass,is }

2、編譯器允許你將泛型引數顯示強制轉換到其他任何藉口,但不能將其轉換到類

inte***ce   is

class   someclass

class   myclass   //沒有約束 }

3、可以使用臨時的object變數,將泛型引數強制轉換到其他任何型別

class   someclass

class   myclass   }

注意:這裡只是告訴你這樣寫是可以的,但是要不要這樣寫?不要這樣寫,因為如果t確實沒有繼承someclass編譯沒錯但是執行就會出錯

4、解決上面強制轉換問題,可以使用is和as運算子進行判斷

public   class   myclass

if   (t   is   linkedlist )

//如果泛型引數的型別是所查詢的型別,則is運算子返回true

string   str   =   t   as   string;

//如果這寫型別相容,則as將執行強制型別轉換,否則將返回null

if   (str   !=   null)

linkedlist list   =   t   as   linkedlist ;

if   (list   !=   null)

} }

七:繼承和泛型

1、在從泛型基類派生,可以提供型別實參,而不是基類泛型引數

public   class   baseclass

public   class   subclass:baseclass

2、如果子類是泛型,而非具體的型別實參,則可以使用子類泛型引數作為泛型基類的指定型別

public   class   baseclass

public   class   subclass :baseclass

3、在使用子類泛型引數時,必須在子類級別重複在基類級別規定的任何約束

4、基類可以定義其簽名使用泛型引數的虛禮方法,在重寫它們時,子類必須在方法簽名中提供相應的型別。

如: public   class   baseclass }

public   class   subclass:baseclass }

5、如果該子類是泛型,則它還可以在重寫時使用它自己的泛型引數

public   class   subclass :baseclass }

6、你可以定義泛型介面、泛型抽象類,甚至泛型抽象方法。

7、不能對泛型引數使用+或+=之類的運算子

public   class   calculator }

但是我們可以通過泛型抽象類、介面來實現在個功能,因為實現泛型抽象類、介面我們就已經明確傳乙個引數了,就可以執行諸如+這樣的操作。

八:泛型方法

1、方法可以定義特定於其執行範圍的泛型引數

public   class   myclass }

2、即使各包含類根本不使用泛型,你也可以定義方法特定的泛型引數

public   class   myclass }

注意:該功能只使用於方法,屬性,索引器只能使用在類的作用範圍中定義的泛型引數。

3、呼叫泛型方法

myclass   obj   =   new   myclass();

obj.mymethod (3);

也可以這樣:

myclass   obj   =   new   myclass();

obj.mymethod(3);   //該功能稱為泛型推理

4、泛型方法也可以有自己的泛型引數約束

pubic   class   myclass }

5、子類方法實現不能重複在父級別出現的約束

public   class   baseclass }

pubic   class   subclass:baseclass }

6、靜態方法

靜態方法可以定義特定的泛型引數和約束

public   class   myclass }

int   number   =   myclass .somemethod (3,"aaa");

或者:int   mumber   =   myclass .somemethod(3,"aaa");

九:泛型委託

1、在某個類中定義的委託可以利用該類的泛型引數

2、委託也可以定義自己的泛型引數

自然語言也支援泛型

什麼是自然語言?自然語言通常是指一種自然地隨文化演化的語言。英語 漢語 日語為自然語言的例子,而世界語則為人造語言,即是一種由人蓄 意為某些特定目的而創造的語言。不過,有時所有人類使用的語言 包括上述自然地隨文化演化的語言,以及人造語言 都會被視為 自然 語言,以相對於如 程式語言等為計算機而設的 ...

隨想錄(從apple的swift語言說起)

1 關於程式語言 2 只是乙個前端 3 基本的邏輯沒變 4 不變的服務端設計 不管什麼客戶端,輸出的資料都要通過socket傳到伺服器進行處理。伺服器 的編寫沒有客戶端那麼花哨,永遠都是socket accept sql訪問 併發訪問 互斥管理 登陸驗證 防止資源洩漏 資料壓縮校驗加密等等。大多數伺...

什麼是自然語言處理,自然語言處理目前的應用有哪些?

自然語言處理大體包括了自然語言理解和自然語言生成兩個部分,實現人機間自然語言通訊意味著要使計算機既能理解自然語言文字的意義,也能以自然語言文本來表達給定的意圖 思想等,前者稱為自然語言理解,後者稱為自然語言生成。自然語言處理是電腦科學領域與人工智慧領域中的乙個重要方向。自然語言處理的終極目標是用自然...