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

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

C# 2.0 Specification(匿名方法)(二)

2024-07-21 02:20:08
字體:
供稿:網(wǎng)友
21.7委托實(shí)例相等性
如下規(guī)則適用由匿名方法委托實(shí)例的相等運(yùn)算符(§7.9.8)和object.equals方法產(chǎn)生的結(jié)果。

l 當(dāng)委托實(shí)例是由具有相同被捕獲外部變量集合的語義相同的匿名方法表達(dá)式計(jì)算而產(chǎn)生時(shí),可以說(但不是必須)它們相等。

l 當(dāng)委托實(shí)例由具有語義不同的匿名方法表達(dá)式,或具有不同的被捕獲外部變量集合時(shí),它們決不相等。



21.8明確賦值
匿名方法參數(shù)的明確賦值狀態(tài)與命名方法是相同的。也就是,引用參數(shù)和值參數(shù)被明確的賦初值,而輸出參數(shù)不用賦初值。并且,輸出參數(shù)在匿名方法正常返回之前必須被明確賦值(§5.1.6)。

當(dāng)控制轉(zhuǎn)換到匿名方法表達(dá)式的程序塊時(shí),對外部變量v的明確賦值狀態(tài),與在匿名方法表達(dá)式之前的v的明確賦值狀態(tài)是相同的。也就是,外部變量的明確賦值將從匿名方法表達(dá)式上下文被繼承。在匿名方法程序塊內(nèi),明確賦值將和在普通程序塊內(nèi)一樣而得到演繹(§5.3.3)。

在匿名方法表達(dá)式之后的變量v的明確賦值狀態(tài)與在匿名方法表達(dá)式之前它的明確賦值狀態(tài)相同。



例如

delegate bool filter(int i);

void f() {
int max;

// 錯(cuò)誤,max沒有明確賦值
filter f = delegate(int n) { return n < max; }

max = 5;
dowork(f);
}

將產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤,因?yàn)閙ax沒有在匿名方法聲明的地方明確賦值。示例

delegate void d();

void f() {
int n;
d d = delegate { n = 1; };

d();

//錯(cuò)誤,n沒有明確賦值
console.writeline(n);
}

也將產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤,因?yàn)槟涿椒▋?nèi)n的賦值,對于該匿名方法外部n的明確賦值狀態(tài)沒有效果。

21.9方法組轉(zhuǎn)換
與在§21.3中描述的隱式匿名方法轉(zhuǎn)換相似,也存在從方法組(§7.1)到兼容的委托類型的隱式轉(zhuǎn)換。

對于給定的方法組e和委托類型d,如果允許new d(e)形式的委托創(chuàng)建表達(dá)式(§7.5.10.3 和 §20.9.6),那么就存在從e到d的隱式轉(zhuǎn)換,并且轉(zhuǎn)換的結(jié)果恰好等價(jià)于new d(e)。

在以下示例中

using system;
using system.windows.forms;

class alertdialog
{
label message = new label();
button okbutton = new button();
button cancelbutton = new button();`





public alertdialog() {
okbutton.click += new eventhandler(okclick);
cancelbutton.click += new eventhandler(cancelclick);
...
}

void okclick(object sender, eventargs e) {
...
}

void cancelclick(object sender, eventargs e) {
...
}
}

構(gòu)造函數(shù)用new創(chuàng)建了兩個(gè)委托實(shí)例。隱式方法組轉(zhuǎn)換允許將之簡化為

public alertdialog() {
okbutton.click += okclick;
cancelbutton.click += cancelclick;
...
}

對于所有其他隱式和顯式的轉(zhuǎn)換,轉(zhuǎn)換運(yùn)算符可以用于顯式地執(zhí)行一個(gè)特定的轉(zhuǎn)換。為此,示例

object obj = new eventhandler(mydialog.okclick);

可被代替寫成如下的樣子。

object obj = (eventhandler)mydialog.okclick;

方法組合匿名方法表達(dá)式可以影響重載決策(overload resolution),但它們并不參與類型推斷。請參見§20.6.4獲取更詳細(xì)的信息。



21.10實(shí)現(xiàn)例子
本節(jié)以標(biāo)準(zhǔn)c#的構(gòu)件形式描述匿名方法的可能實(shí)現(xiàn)。在這里描述的實(shí)現(xiàn)基于microsoft c#編譯器所采用的相同原則,但它決不是強(qiáng)制性的或唯一可能的實(shí)現(xiàn)。

本節(jié)的后面部分給出了幾個(gè)示例代碼,它包含了具有不同特性的匿名方法。對于每個(gè)例子,我們將提供使用唯一標(biāo)準(zhǔn)c#構(gòu)件的代碼的對應(yīng)轉(zhuǎn)換。在這些例子中,標(biāo)識符d假定表示如下委托類型。

public delegate void d();



匿名方法的最簡形式就是沒有捕獲外部變量的那個(gè)。

class test
{
static void f() {
d d = delegate { console.writeline("test"); };
}
}

這段代碼可被轉(zhuǎn)換到一個(gè)引用編譯器生成的靜態(tài)方法的委托實(shí)例,而匿名方法的代碼將會放入到該靜態(tài)方法中。、

class test
{
static void f() {
d d = new d(__method1);
}

static void __method1() {
console.writeline("test");
}
}



在下面的示例中,匿名方法引用this的實(shí)例成員。

class test
{
int x;

void f() {
d d = delegate { console.writeline(x); };
}
}

this可以被轉(zhuǎn)換到由編譯器生成的包含匿名方法代碼的實(shí)例方法。

class test
{
int x;

void f() {
d d = new d(__method1);
}

void __method1() {
console.writeline(x);
}
}

在這個(gè)例子中,匿名方法捕獲了一個(gè)局部變量。





class test
{
void f() {
int y = 123;
d d = delegate { console.writeline(y); };
}
}

該局部變量的生存期現(xiàn)在至少必須延長到匿名方法委托的生存期為止。這可以通過將局部變量“提升(lifting)”為編譯器生成的(compiler-generated)類的字段來完成。局部變量的實(shí)例化對應(yīng)于創(chuàng)建一個(gè)編譯器生成的類的實(shí)例,而訪問局部變量將對應(yīng)于訪問編譯器生成的類實(shí)例的一個(gè)字段。并且,匿名方法將成為編譯器生成類的實(shí)例方法。

class test
{
void f() {
__locals1 = new __locals1();
__locals1.y = 123;
d d = new d(__locals1.__method1);
}

class __locals1
{
public int y;

public void __method1() {
console.writeline(y);
}
}
}

最后,如下匿名方法將捕獲this,以及具有不同生存期的兩個(gè)局部變量。

class test
{
int x;

void f() {
int y = 123;
for (int i = 0; i < 10; i++) {
int z = i * 2;
d d = delegate { console.writeline(x + y + z); };
}
}
}



在這里,編譯器將為每個(gè)語句塊生成類,在這些語句塊中局部變量將被捕獲,而在不同塊中的局部變量將會有獨(dú)立的生存期。



__locals2的實(shí)例,編譯器為內(nèi)部語句塊生成的類,包含局部變量z和引用__locals1實(shí)例的字段。__locals1的實(shí)例,編譯器為外部語句塊生成的類,包含局部變量y和引用封閉函數(shù)成員的this的字段。通過這些數(shù)據(jù)結(jié)構(gòu),你可以通過__locals2的一個(gè)實(shí)例到達(dá)所有被捕獲的局部變量,并且匿名方法的代碼可以作為那個(gè)類的實(shí)例方法而實(shí)現(xiàn)。

class test
{
void f() {
__locals1 = new __locals1();
__locals1.__this = this;
__locals1.y = 123;
for (int i = 0; i < 10; i++) {
__locals2 = new __locals2();
__locals2.__locals1 = __locals1;
__locals2.z = i * 2;
d d = new d(__locals2.__method1);
}
}

class __locals1
{
public test __this;
public int y;
}

class __locals2
{
public __locals1 __locals1;
public int z;

public void __method1() {
console.writeline(__locals1.__this.x + __locals1.y + z);
}
}
}

(匿名方法完)
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 罗山县| 轮台县| 类乌齐县| 芦溪县| 环江| 常熟市| 汾西县| 修武县| 房产| 额尔古纳市| 调兵山市| 萝北县| 乌鲁木齐市| 沙湾县| 安溪县| 班玛县| 台中县| 黄浦区| 井研县| 西青区| 沅陵县| 宜兰县| 教育| 高密市| 汶川县| 翁源县| 武定县| 长子县| 凤庆县| 崇文区| 都匀市| 旅游| 商南县| 富阳市| 通化县| 全州县| 墨玉县| 荔浦县| 桐乡市| 林周县| 固原市|