国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

C# 2.0 Specification (泛型三)

2024-07-21 02:20:02
字體:
供稿:網(wǎng)友
菜鳥學堂:
接泛型二
這篇文章是翻譯的微軟的技術(shù)文章.供學習c#的朋友參考,請勿用于商業(yè)目的。http://msdn.microsoft.com/vcsharp/team/language/default.aspx
20.4 泛型委托聲明
委托聲明可以包含類型參數(shù)。

delegate-declaration:

attributes opt delegate-modifiers op t delegate return-type identifier type-parameter-list opt

(formal-parameter-list opt) type-parameter-constraints-clauses opt;

(委托聲明: 特性可選 委托修飾符可選 delegate 返回類型 標識符 類型參數(shù)列表可選 (正式參數(shù)列表可選 )類型參數(shù)約束語句可選

使用類型參數(shù)聲明的委托是一個泛型委托聲明。委托聲明只有在支持類型參數(shù)列表時,才能支持類型參數(shù)約束語句(§20.7)。除了所指出的之外,泛型委托聲明和常規(guī)的委托聲明遵循相同的規(guī)則。泛型委托聲明中的每個類型參數(shù),在與委托關(guān)聯(lián)的特定聲明空間(§3.3)定義了一個名字。在委托聲明中的類型參數(shù)的作用域包括返回類型、正式參數(shù)列表和類型參數(shù)約束語句。

像其他泛型類型聲明一樣,必須給定類型實參以形成構(gòu)造委托類型。構(gòu)造委托類型的參數(shù)和返回值,由委托聲明中構(gòu)造委托類型的每個類型參數(shù)對應(yīng)的實參替代所形成。而結(jié)果返回類型和參數(shù)類型用于確定什么方法與構(gòu)造委托類型兼容。例如

delegate bool predicate<t>(t value)

class x

{

static bool f(int i){…}

static bool g(string s){…}





static void main(){

predicate<int> p1 = f;

predicate<string> p2=g;

}

}

注意在先前的main方法中的兩個賦值等價于下面的較長形式.

static void main(){

predicate<int> p1 = new predicate<int>(f);

predicate<string> p2 = new predicate<string>(g);

}

由于方法組轉(zhuǎn)換,較短的形式也是可以的,這在§21.9中有說明。



20.5構(gòu)造類型
泛型類型聲明自身并不表示一個類型。相反,泛型類型聲明通過應(yīng)用類型實參的方式被用作形成許多不同類型的“藍圖”。類型參數(shù)被寫在尖括號之間,并緊隨泛型類型聲明名字之后。使用至少一個實參而被命名的類型被稱為構(gòu)造類型(constructed type)。構(gòu)造類型可以用在語言中類型名字可以出現(xiàn)的大多數(shù)地方。

type-name:(類型名字:)

namespace-or-type-name(命名空間或類型名字)

namespace-or-type-name:(命名空間或類型名字:)

identifier type-argument-list(標識符類型實參列表可選)

namespace-or-type-name. identifier(命名空間或類型名字.標識符)

type-argument-list opt(類型實參列表可選)



構(gòu)造類型也能被用在表達式中作為簡單名字(§20.9.3)或者訪問一個成員(§20.9.4)。

當一個命名空間或類型名字被計算時,只有帶有正確數(shù)量類型參數(shù)的泛型類型會被考慮。由此,只要類型有不同數(shù)量的類型參數(shù)并且聲明在不同的命名空間,那么使用相同的標識符標識不同的類型是可能的。這對于在同一程序中混合使用泛型和非泛型類是很有用的。

namespace system.collections

{

class queue{…}

}



namespace sysetm.collections.generic

{

class queue<elementtype>{…}

}

namespace myapplication

{

using system.collections;

using system.collections.generic;

class x

{

queue q1; //system.collections.queue

queue<int> q2;//system.collections.generic.queue

}

}



在這些代碼中對于名字查找的詳細規(guī)則在§20.9中進行了描述。在這些代碼中對于模糊性的決議在§20.6.5中進行了描述。

類型名字可能標識一個構(gòu)造類型,盡管它沒有直接指定類型參數(shù)。這種情況在一個類型嵌套在一個泛型類聲明中時就會出現(xiàn),并且包含聲明的實例類型將因為名字查找(§20.1.2)而被隱式地使用。

class outer<t>

{

public class inner{…}

public inner i; //i的類型是outer<t>.inner

}



在不安全代碼中,構(gòu)造類型不能被用作非托管類型(§18.2)。

20.5.1類型實參
在一個類型參數(shù)列表中的每個實參都只是一個類型。

type-argument-list:(類型實參列表:)

<type-arguments>(<類型實參>)

type-arguments:(類型實參:)

type-argument(類型實參)

type-arguments, type-argument(類型實參,類型實參)

type-argument:(類型實參:)

type(類型)



類型實參反過來也可以是構(gòu)造類型或類型參數(shù)。在不安全代碼中(§18),類型實參不能是指針類型。每個類型實參必須遵循對應(yīng)類型參數(shù)(§20.7.1)上的任何約束。



20.5.2開放和封閉類型
所有類型都可以被分為開放類型(open type)或封閉類型(closed type)。開放類型是包含類型參數(shù)的類型。更明確的說法是

類型參數(shù)定義了一個開放類型
數(shù)組類型只有當其元素是一個開放類型時才是開放類型
構(gòu)造類型只有當其類型實參中的一個或多個是開放類型時,它才是開放類型


非開放類型都是封閉類型。



在運行時,在泛型類型聲明中的所有代碼都在一個封閉構(gòu)造類型的上下文執(zhí)行,這個封閉構(gòu)造類型是通過將類型實參應(yīng)用到泛型聲明中創(chuàng)建的。在泛型類型中的每個類型實參被綁定到一個特定運行時類型。所有語句和表達式的運行時處理總是針對封閉類型發(fā)生,而開放類型只發(fā)生在編譯時處理。

每個封閉構(gòu)造類型都有它自己的一組靜態(tài)變量,它們并不被其他封閉類型共享。因為在運行時不存在開放類型,所以開放類型沒有關(guān)聯(lián)的靜態(tài)變量。如果兩個封閉構(gòu)造類型是從同一個類型聲明構(gòu)造的,并且對應(yīng)的類型實參也是相同的類型,那么它們就是相同的類型。



20.5.3構(gòu)造類型的基類和接口
構(gòu)造類類型有一個直接基類,就像是一個簡單類類型。如果泛型類聲明沒有指定基類,其基類為object。如果基類在泛型類聲明中被指定,構(gòu)造類型的基類通過將在基類聲明中的每個類型參數(shù),替代為構(gòu)造類型對應(yīng)類型實參而得到。給定泛型類聲明

class b<u , v>{…}

class g<t>:b<string , t[]>{…}

構(gòu)造類型g<int>的基類將會是b<string , int[]>。

相似地,構(gòu)造類、結(jié)構(gòu)和接口類型有一組顯式的基接口。顯式基接口通過接受泛型類型聲明中的顯式基接口聲明和某種替代而形成,這種替代是將在基接口聲明中的每個類型參數(shù),替代為構(gòu)造類型的對應(yīng)類型實參。



一個類型的所有基類和基接口通過遞歸地得到中間基類和接口的基類與接口而形成。例如,給定泛型類聲明



class a {…}

class b<t>:a{…}

class c<t>:b<icomparable<t>>{…}

class d<t>:c<t[]>{…}

d<int>的基類是c<int[]>,b<icomparable<int[]>>,a和object。

20.5.4構(gòu)造類型的成員
構(gòu)造類型的非繼承成員通過替代成員聲明的類型實參,構(gòu)造類型的對應(yīng)類型實參而得到。

例如,給定泛型類聲明

class gen<t,u>

{

public t[,],a;

public void g(int i ,t t , gen<u, t> gt){…}

public u prop(get{…}) set{…}}

public int h{double d}{…}

}



構(gòu)造類型gen<int[],icomparable<string>>有如下的成員。

public int[,][] a;

public void g(int i , int[] t , gen<icomparable<string>,int[] gt>){…}

public icomparable<string> prop{get{…} set{…}}

public int h(double d){…}

注意替代處理是基于類型聲明的語義意義的,并不是簡單的基于文本的替代。在泛型類聲明gen中的成員a的類型是“t的二維數(shù)組” 因此在先前實例化類型中的成員a的類型是“int型的一維數(shù)組的二維數(shù)組”或int[,][]。

構(gòu)造類型的繼承成員以一種相似的方法得到。首先直接基類的所有成員是已經(jīng)確定的。如果基類自身是構(gòu)造類型這可能包括當前規(guī)則的遞歸應(yīng)用。然后,繼承成員的每一個通過將成員聲明中的每個類型參數(shù),替代為構(gòu)造類型對應(yīng)類型實參而被轉(zhuǎn)換。

class b<u>

{

public u f(long index){…}

}



class d<t>:b<t[]>

{

public t g(string s){…}

}

在先前的例子中,構(gòu)造類型d<int>的非繼承成員public int g(string s)通過替代類型參數(shù)t的類型實參int而得到。d<int>也有一個從類聲明b而來的繼承成員。這個繼承成員通過首先確定構(gòu)造類型b<t[]>的成員而被確定,b<t[]>成員的確定是通過將u替換為替換為t[],產(chǎn)生public t[] f(long index)。然后類型實參int替換了類型參數(shù)t,產(chǎn)生繼承成員public int[] f(long index)。



20.5.5構(gòu)造類型的可訪問性
當構(gòu)造類型c<t1,…,tn>的所有部分c,t1,…,tn 可訪問時,那么它就是可訪問的。例如,如果泛型類型名c是public,并且所有類型參數(shù)t1,…,tn也是public ,那么構(gòu)造類型的可訪問性也是public 。如果類型名或類型實參之一是private,那么構(gòu)造類型的可訪問性是private。如果類型實參之一可訪問性是protected,另一個是internal,那么構(gòu)造類型的可訪問性僅限于該類,以及本程序集之內(nèi)的子類。

20.5.6轉(zhuǎn)換
構(gòu)造類型遵循與非泛型類型相同的規(guī)則(§6)。當應(yīng)用這些規(guī)則時,構(gòu)造類型的基類和接口必須按§20.5.3中所描述的方式確定。

除了那些在§6中所描述的之外,構(gòu)造引用類型之間不存在特別的轉(zhuǎn)換。尤其是,不像數(shù)組類型,構(gòu)造引用類型不允許“co-variant”轉(zhuǎn)換。也就是說,類型list<b>不能轉(zhuǎn)換到類型list<a>(無論是隱式或顯式)即使是b派生于a也是如此。同樣,也不存在從list<b>到list<object>的轉(zhuǎn)換。

對于這一點的基本原理是很簡單的:如果可以轉(zhuǎn)換到list<a>,很顯然你可以存儲一個類型a的值到這個list中。這將破壞在list<b>類型中的每個對象總是類型b的值這種不變性,或者當在集合類上賦值時,將出現(xiàn)不可預料的錯誤。



轉(zhuǎn)換的行為和運行時類型檢查演示如下。

class a {…}

class b:a{…}

class colletion{…}

class list<t>:collection{…}

class test

{

void f()

{

list<a> lista = new list<a>();

list<b> listb= new list<b>();

collection c1 = lista; //ok,list<a>是一個集合

collection c2 = listb; //ok,list<b>是一個集合

list<a> a1 = listb; //錯誤,沒有隱式的轉(zhuǎn)換

list<a> a2 = (list<a>)listb; //錯誤,沒有顯式的轉(zhuǎn)換

}

}



20.5.7system.nullable<t>類型
在.net基類庫中定義了泛型結(jié)構(gòu)類型system.nullable<t>泛型結(jié)構(gòu)類型,它表示一個類型t的值可以為null。system.nullable<t>類型在很多情形下是很有用的,例如用于指示數(shù)據(jù)庫表的可空列,或者xml元素中的可選特性。

可以從一個null類型向任何由system.nullable<t>類型構(gòu)造的類型作隱式地轉(zhuǎn)換。這種轉(zhuǎn)換的結(jié)果就是system.nullable<t>的默認值。也就是說,可以這樣寫

nullable<int> x = null;

nullable<string> y = null;

和下面的寫法相同。

nullable<int> x = nullable<int>.default;

nullable<string> y = nullable<string>.default;



20.5.8使用別名指令
使用別名可以命名一個封閉構(gòu)造類型,但不能命名一個沒有提供類型實參的泛型類型聲明。例如

namespace n1

{

class a<t>

{

class b{}

}



class c{}

}

namespace n2

{

using w = n1.a; //錯誤,不能命名泛型類型

using x = n1.a.b; //錯誤,不能命名泛型類型

using y = n1.a<int>; //ok,可以命名封閉構(gòu)造類型

using z = n1.c; //ok

}

20.5.9特性
開放類型不能被用于特性內(nèi)的任何地方。一個封閉構(gòu)造類型可以被用作特性的實參,但不能被用作特性名,因為system.attribute不可能是泛型類聲明的基類。

class a:attribute

{

public a(type t){…}

}

class b<t>: attribute{} //錯誤,不能將attribute用作基類

class list<t>

{

[a(typeof(t))] t t; //錯誤,在特性中有開放類型

}

class x

{

[a(typeof(list<int>))] int x; //ok,封閉構(gòu)造類型

[b<int>] int y; //錯誤,無效的特性名字

}


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 昌都县| 忻州市| 鲁甸县| 马鞍山市| 东乡县| 开封市| 孝昌县| 萨迦县| 福泉市| 佳木斯市| 界首市| 武安市| 漳浦县| 延长县| 北川| 泉州市| 湘阴县| 囊谦县| 木里| 曲水县| 东丽区| 巴林左旗| 锦州市| 礼泉县| 繁峙县| 武山县| 沂水县| 米林县| 宾川县| 霞浦县| 广南县| 丹东市| 蓬莱市| 阿拉尔市| 嘉鱼县| 乐山市| 稻城县| 泸定县| 商丘市| 顺昌县| 宽城|