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

來源:互聯網
上載者:User

21.7委託執行個體相等性

如下規則適用由匿名方法委託執行個體的相等運算子(§7.9.8)和object.Equals方法產生的結果。
l 當委託執行個體是由具有相同被捕獲外部變數集合的語義相同的匿名方法運算式計算而產生時,可以說(但不是必須)它們相等。
l 當委託執行個體由具有語義不同的匿名方法運算式,或具有不同的被捕獲外部變數集合時,它們決不相等。

21.8明確賦值

匿名方法參數的明確賦值狀態與命名方法是相同的。也就是,引用參數和值參數被明確的賦初值,而輸出參數不用賦初值。並且,輸出參數在匿名方法正常返回之前必須被明確賦值(§5.1.6)。
當控制轉換到匿名方法運算式的程式塊時,對外部變數v的明確賦值狀態,與在匿名方法運算式之前的v的明確賦值狀態是相同的。也就是,外部變數的明確賦值將從匿名方法運算式上下文被繼承。在匿名方法程式塊內,明確賦值將和在普通程式塊內一樣而得到演繹(§5.3.3)。
在匿名方法運算式之後的變數v的明確賦值狀態與在匿名方法運算式之前它的明確賦值狀態相同。

例如

delegate bool Filter(int i);void F() {int max;// 錯誤,max沒有明確賦值Filter f = delegate(int n) { return n < max; }max = 5;DoWork(f);}

將產生一個編譯時間錯誤,因為max沒有在匿名方法聲明的地方明確賦值。樣本

delegate void D();void F() {int n;D d = delegate { n = 1; };d();//錯誤,n沒有明確賦值Console.WriteLine(n);}

也將產生一個編譯時間錯誤,因為匿名方法內n的賦值,對於該匿名方法外部n的明確賦值狀態沒有效果。

21.9方法群組轉換

與在§21.3中描述的隱式匿名方法轉換相似,也存在從方法組(§7.1)到相容的委託類型的隱式轉換。
對於給定的方法組E和委託類型D,如果允許new D(E)形式的委託建立運算式(§7.5.10.3 和 §20.9.6),那麼就存在從E到D的隱式轉換,並且轉換的結果恰好等價於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) {...}}

建構函式用new建立了兩個委託執行個體。隱式方法群組轉換允許將之簡化為

public AlertDialog() {okButton.Click += OkClick;cancelButton.Click += CancelClick;...}

對於所有其他隱式和顯式的轉換,轉換運算子可以用於顯式地執行一個特定的轉換。為此,樣本

object obj = new EventHandler(myDialog.OkClick);

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

object obj = (EventHandler)myDialog.OkClick;

方法組合匿名方法運算式可以影響重載決策(overload resolution),但它們並不參與類型推斷。請參見§20.6.4擷取更詳細的資訊。

21.10實現例子

本節以標準C#的構件形式描述匿名方法的可能實現。在這裡描述的實現基於Microsoft C#編譯器所採用的相同原則,但它決不是強制性的或唯一可能的實現。
本節的後面部分給出了幾個範例程式碼,它包含了具有不同特性的匿名方法。對於每個例子,我們將提供使用唯一標準C#構件的代碼的對應轉換。在這些例子中,標識符D假定表示如下委託類型。

public delegate void D();

匿名方法的最簡形式就是沒有捕獲外部變數的那個。

class Test{static void F() {D d = delegate { Console.WriteLine("test"); };}}

這段代碼可被轉換到一個引用編譯器產生的靜態方法的委託執行個體,而匿名方法的代碼將會放入到該靜態方法中。、

class Test{static void F() {D d = new D(__Method1);}static void __Method1() {Console.WriteLine("test");}}

在下面的樣本中,匿名方法引用this的執行個體成員。

class Test{int x;void F() {D d = delegate { Console.WriteLine(x); };}}

this可以被轉換到由編譯器產生的包含匿名方法代碼的執行個體方法。

class Test{int x;void F() {D d = new D(__Method1);}void __Method1() {Console.WriteLine(x);}}

在這個例子中,匿名方法捕獲了一個局部變數。


class Test{void F() {int y = 123;D d = delegate { Console.WriteLine(y); };}}

該局部變數的生存期現在至少必須延長到匿名方法委託的生存期為止。這可以通過將局部變數“提升(lifting)”為編譯器產生的(compiler-generated)類的欄位來完成。局部變數的執行個體化對應於建立一個編譯器產生的類的執行個體,而訪問局部變數將對應於訪問編譯器產生的類執行個體的一個欄位。並且,匿名方法將成為編譯器產生類的執行個體方法。

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,以及具有不同生存期的兩個局部變數。

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); };}}}

在這裡,編譯器將為每個語句塊產生類,在這些語句塊中局部變數將被捕獲,而在不同塊中的局部變數將會有獨立的生存期。

__Locals2的執行個體,編譯器為內部語句塊產生的類,包含局部變數z和引用__Locals1執行個體的欄位。__Locals1的執行個體,編譯器為外部語句塊產生的類,包含局部變數y和引用封閉函數成員的this的欄位。通過這些資料結構,你可以通過__Locals2的一個執行個體到達所有被捕獲的局部變數,並且匿名方法的代碼可以作為那個類的執行個體方法而實現。

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);}}}

(匿名方法完)


以上就是C# 2.0 Specification(匿名方法)(二)的內容,更多相關內容請關注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.