亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C#LanguageSpecification5.0(翻譯)第五章變量

2019-11-14 14:07:48
字體:
來源:轉載
供稿:網友

C# Language Specification 5.0

變量(variable)表示存儲的位置。每個變量都有類型,類型決定變量保存的值的類型。C# 是一門類型安全的語言,C# 編譯器會確保變量中保存一個適合類型的值。變量的值可通過賦值或通過使用 ++-- 操作符改變。

變量必須在獲得(obtained)前被明確賦值(definitely assigned)(第五章第三節)。

如以下部分所述,變量要么初始已賦值(initially assigned),要么初始未賦值(initially unassigned)。初始已賦值的變量有非常明確(well-defined)的初始值,且視己為被明確賦值(definitely assigned)的。初始未賦值的變量沒有初始值(initial value)。對于初始未賦值變量來說,為了在某個位置能明確賦值,必須在通往該位置的每一個可能執行到的分支對該變量賦值。


變量種類

C# 定義了七種變量:靜態變量(static variables)、實例變量(instance variables)、數組元素(array elements)、值參數(value parameters)、引用參數(reference parameters)、輸出參數(output parameters)和局部變量(local variables)。本節將對上述類型逐一介紹。

下例中

class A{    public static int x;    int y;    void F(int[] v, int a, ref int b, out int c) {        int i = 1;        c = a + b++;    }}

x 是靜態變量,y 是實例變量,v[0] 是數組元素,a 是值參數,b 是引用參數,c 是輸出參數,i 是局部變量。

靜態變量

以靜態修飾符 static 聲明的字段被稱為靜態變量(static variable)。靜態變量在其所在類型的靜態構造函數(第十章第十二節)執行之前便已存在,當其所相關的應用域(application domain)退出時不再存在。

靜態變量的初始值是其類型的默認值(第五章第二節)。

為了明確賦值檢查,靜態變量被視為初始已賦值的。

實例變量

不以靜態修飾符 static 聲明的字段叫做實例變量(instance variable)。

類中的實例變量

類的實例變量在該類被創建實例時開始存在,當所有對該實例的引用都終止、實例析構函數(若有)執行過后,該類的實例變量不再存在。

類實例變量的初始值是該變量類型的默認值(第五章第二節)。

為了明確賦值檢查,類的實例變量被認為是初始已賦值的。

結構中的實例變量

結構實例變量的生命周期與其所屬的結構變量是一樣的。換句話說,當結構類型的變量存在或終止時,它的實例變量也隨之存在或消失。

結構的實例變量的初始賦值狀態與其所在的結構變量一樣。換句話說,當結構變量被視為初始化已賦值時,其實例變量也被視為初始化已賦值;當結構變量被視為初始化未賦值時,其實例變量也為初始化未賦值。

數組元素

當數組實例被創建時,數組元素開始存在;當沒有任何引用指向該數組實例時,數組元素消失。

數組的每一個元素的初始值均為該數組元素類型的默認值(第五章第二節)。

為了明確賦值檢查,數組元素被認為是初始已賦值的。

值參數

不使用 refout 修飾符的參數聲明叫做值參數(value parameter)。

值形參再調用該參數所屬的函數成員(方法、實例構造函數、訪問器或操作符)或匿名函數時開始存在,并由調用者提供的實參的值初始化。一般來說,值形參的存在直到函數成員或匿名函數返回結果為止。然而,如果值形參如果被匿名函數(第七章第十五節)捕獲(capture),則其生命周期將被至少延長到由該匿名函數創建的委托或表達式樹可被垃圾回收為止。

為了明確賦值檢查,值參數被認為是初始已賦值的。

引用參數

使用 ref 修飾符的參數聲明叫做引用參數(reference parameter)。

引用形參不會創建新的本地存儲位置。相反,引用形參表示其存儲位置與函數成員或匿名函數調用所給定的實參的存儲位置是一樣的。因此,引用形參的值總是與基礎變量相同。

下面的明確賦值規則適用于引用形參。注意,對輸出形參(output parameters)規則與第五章第 1.6 節中所描述的規則不同。

  • 變量必須在它被以引用參數形式傳入函數成員或委托調用之前被明確賦值(第五章第三節)。
  • 在函數成員或匿名函數內,引用形參被視為已被賦值。

在結構類型的實例方法或實例訪問器中,this 關鍵字的行為與該結構類型所引用的形參相同(第七章第 6.7 節)。

輸出參數

使用 out 修飾符的參數聲明叫做輸出參數(output parameter)。

輸出形參不會創建新的本地存儲位置。相反,輸出形參表示與函數成員或委托調用所給定的存儲位置是一樣的。因此,輸出形參的值總是與基礎變量相同。

下面的明確賦值規則適用于輸出形參。注意,對引用形參(reference parameters)規則與第五章第 1.5 節中所描述的規則不同。

  • 變量不必在以輸出形參的方式傳入函數成員或委托調用之前明確初始化。
  • 在正常完成函數成員或委托調用之后,每一個以輸出形參的形式傳入的變量都被認為在執行路徑(execution path)中賦值。
  • 在函數成員或匿名函數內部,輸出形參被視為初始未賦值。
  • 每一個函數成員或匿名函數的輸出形參必須在函數成員或匿名函數正常返回結果之前被明確賦值(第五章第三節)。

在結構類型的實例方法中,this 關鍵字的行為與該結構類型所輸出的形參相同(第七章第 6.7 節)。

局部變量

局部變量(local variable)local-variable-declaration 所聲明,可出現在 block、for-statement、switch-statementusing-statement 內;或由 foreach-statementspecific-catch-clausetry-statement 聲明。

局部變量的生命周期是程序執行期間的一部分,在此期間定會為其保留存儲。這個生命周期至少從進入相關的 blockfor-statement、switch-statement、using-statement、foreach-statementspecific-catch-clause 開始,到該 block、for-statement、switch-statement、using-statement、foreach-statementspecific-catch-clause 以任何方式結束為止。(進入閉包的 block 或方法調用會掛起(suspends)——但不會結束——當前的 block、for-statement、switch-statement、using-statement、foreach-statementspecific-catch-clause。)如果局部變量被匿名函數(第七章第 15.5.1 節)捕獲,其生命周期至少延長到從該匿名函數創建的委托或表達式樹,以及其它引用該捕獲變量的對象可被垃圾回收為止。

如果遞歸地進入(entered recursively)父 block、for-statement、switch-statement、using-statement、foreach-statementspecific-catch-clause,每次都會創建該局部變量的新實例,并重新計算其 local-variable-initializer(若有)。

local-variable-declaration 引入的局部變量不會自動初始化,因此沒有默認值。為了明確賦值檢查的目的,由 local-variable-declaration 引入的局部變量被認為是初始未賦值(initially unassigned)的。local-variable-declaration 可以包括 local-variable-initializer,在此情況下,位于初始化表達式(第五章第 3.3.4 節)之后的變量被視作明確賦值的。

local-variable-declaration 引入的局部變量的范圍內,在 local-variable-declarator 文本位置之前引用該局部變量會導致「編譯時錯誤」。如果局部變量的聲明是隱式的(第八章第 5.1 節),那么在 local-variable-declarator 內引用該變量同樣會報錯。

foreach-statementspecific-catch-clause 引入的局部變量在整個范圍內被視作明確賦值的。

局部變量的實際生命周期是依賴于具體實現的(implementation-dependent)。比方說,編譯器可能靜態地(statically)決定某個塊中的局部變量只用于該塊的一小部分(a small portion of that block)?;诖朔治?,編譯器生成的代碼可能會使該變量的存儲生命周期短于其所在的塊。

局部引用變量所引用的存儲(storage)的回收(reclaimed)獨立于該局部引用變量(第三章第九節)的生命周期


默認值

下列分類的變量將自動初始化其默認值:

  • 靜態變量;
  • 類實例的實例變量;
  • 數組元素。

變量默認值依賴于其變量類型,并由以下規定確定:

  • 對于值類型的變量,默認值與該值類型的默認構造函數(第四章第 1.2 節)所計算出的值相同;
  • 對于引用類型的變量,默認值為空 null。

默認值初始化是一般是內存管理器(memory manager)或垃圾回收器(garbage collector)在分配內存給其使用之前,將內存的「所有位置零(all-bits-zero)」?;诖?,很方便使用「所有位置零」表示空引用(null reference)。


明確賦值

在函數成員可執行代碼中的給定位置,如果編譯器能夠通過特別的靜態流程分析(particular static flow analysis,第五章第 3.3 節)證明變量已被自動初始化(automatically initialized)或至少一次被作為賦值的目標,那么稱變量已被明確賦值。非正式地來講,明確賦值的規則如下:

  • 初始已賦值變量(第五章第 3.1 節)被視作明確賦值的。
  • 如果所有可能的通向指定位置的執行路徑至少包含以下一條,那么稱初始未賦值變量(第五章第 3.2 節)可被視為明確賦值的:
    • 將變量作為左操作數(left Operand)進行簡單賦值(simple assignment,第七章第 17.1 節)。
    • 將變量傳輸到輸出參數作為調用表達式(invocation exPRession,第七章第 6.5 節)或對象創建表達式(object creation expression,第七章第 6.10.1 節)。
    • 對于局部變量,包含變量初始化器(variable initializer)的局部變量聲明(第八章第 5.1 節)。

對于以上這些非正式的規則的正式規范在第五章第 3.1 節、第五章第 3.2 節以及第五章第 3.3 節中介紹。

對于 struct-type 變量之實例變量的明確賦值狀態,既可以單獨跟蹤(tracked individually),也可以整體跟蹤(tracked collectively)。另外除上述規則外,下列規則也將應用于 struct-type 變量及其實例變量:

  • 當實例變量包含已被視作明確賦值的 struct-type 變量時,被視作已被明確賦值;
  • struct-type 變量的每個實例變量都視作明確賦值時,它也被視作明確賦值。

下列上下文是必須明確賦值的:

  • 變量必須在被獲得之前的每一個地方明確賦值,以確保不會出現未定義值。表達式中出現的變量被視作獲取變量的值,除非當:
    • 變量時簡單賦值的左操作數,
    • 變量傳遞為一個輸出參數,或者
    • 變量是 struct-type 變量且作為成員訪問的左操作數出現。
  • 變量必須在作為引用參數(reference parameter)傳遞的每個位置明確賦值,以確保被調用的函數成員能夠調用將之視作初始已賦值。
  • 所有函數成員的輸出參數必須在函數成員返回的每一個位置上明確賦值(通過 return 語句或通過執行到函數成員體的尾部并返回),以確保函數成員不會在輸出參數中返回未定義的值(undefined values),因此允許編譯器把將變量作為輸出參數的函數成員的調用視作等價于對變量的賦值。
  • struct-type 實例構造函數的 this 變量必須在實例構造函數所返回的每一個位置上明確賦值。

初始已賦值變量

以下變量分類被歸入初始已賦值(initially assigned):

  • 靜態變量
  • 類實例的實例變量
  • 初始已賦值的結構變量的實例變量
  • 數組元素
  • 值參數
  • 引用參數
  • 在 catch 子句 或 foreach 語句中的變量聲明

初始未賦值變量

以下變量分類被歸入初始未賦值(initially unassigned):

  • 初始未賦值的結構變量的實例變量
  • 輸出參數,包括結構實例構造函數的 this 變量
  • 局部變量,除了那些聲明于 catch 子句或 foreach 語句的變量

明確賦值的詳細規則

為了確定每個所用變量是否已明確賦值,編譯器必須使用與本節所述之一等價的處理過程。

編譯器會處理每一個具有至少一個初始未賦值變量的函數成員的主體。對于每一個初始未賦值的變量 v,編譯器在以下函數成員內節點確定其明確賦值狀態:

  • 位于每句語句的開頭位置
  • 位于每句語句的結束點(end point,第八章第一節)
  • 在每個將控制轉移到另一句語句或語句結束點的 arc(Automatic Reference Counting)[1]
  • 位于每個表達式的開頭位置
  • 位于每個表達式的結尾位置

v 的明確賦值狀態可以是:

  • 明確賦值的(definitely assigned)。這表明在所有可以到達該點的控制流中,v 都已經賦值。
  • 未明確賦值的(not definitely assigned)。對于位于 bool 類型表達式結尾處變量狀態,其變量狀態為未明確賦值的可能(但不一定)分成下列子狀態(sub-states):
    • 在 true 表達式后明確賦值。這個狀態表明如果 bool 表達式運算結果為 true 時 v 將明確賦值,但當其運算結果為 false 時則不一定。
    • 在 false 表達式時候明確賦值。這個狀態表明如果 bool 表達式運算結果為 false 時 v 將明確賦值,但當其運算結果為 true 時則不一定。

下列規則控制變量 v 在每一個位置上如何決定明確賦值狀態的。

一般語句規則

  • 位于函數成員主體開頭處的 v 是未明確賦值的;
  • 在任何無法訪問的語句的開頭處的 v 都是明確賦值的;
  • 在任何其它語句開頭處 v 的明確賦值狀態由檢查 v 在所有指向該語句開始處的控制流轉移上的明確賦值狀態所決定的。當且僅當 v 在所有此種控制流轉移上是明確賦值的,那么 v 才在語句開頭處是明確賦值的。確定所有可能的控制流轉移集的方法與檢查語句可訪問性的方法(第八章第一節)相同。
  • 在 block、checked、unchecked、if、while、do、for、foreach、lock、using 或 switch 語句結尾點上的 v 的明確賦值狀態由檢查所有指向該語句結尾點的控制流轉移上 v 明確服裝狀態所決定。如果 v 在所有此種控制流轉移上是明確賦值的,那么 v 才在語句結尾點上是明確賦值的。不然的話,v 在語句結尾點上是未明確賦值的。確定所有可能的控制流轉移集的方法與檢查語句可訪問性的方法(第八章第一節)相同。

塊、checked 與 unchecked 語句

在指向某塊(block)語句列表(statement list)中第一句語句(如果語句列表為空(empty)則指向該塊結束點)的控制轉移上 v 的明確賦值狀態與語句、checked 或 unchecked 語句之前的 v 的明確賦值狀態一致。

表達式語句

對于由表達式 expr 組成的表達式語句 stmt

  • 位于 expr 開頭位置的 v 的明確賦值狀態與 stmt 開頭處的一致;
  • 如果 v 在 expr 結尾處是明確賦值的,那么在 stmt 結尾點也是明確賦值的,不然相反。

聲明語句

  • 如果 stmt 是不帶初始化器的聲明語句,則 v 在 stmt 結束點與在 stmt 開頭處具有相同的明確賦值狀態;
  • 如果 stmt 是一個帶初始化器的聲明語句,則確定 v 的明確賦值狀態時可將之視為語句列表,每個帶初始化器的聲明對應一句賦值語句(按聲明的順序)。

if 語句

對于形如以下的 if 語句 stmt

if ( expr ) then-stmt else else-stmt
  • 位于 expr 開頭位置的 v 的明確賦值狀態與 stmt 開頭處一致;
  • 如果 v 在 expr 結尾處是明確賦值的,那么在指向 then-stmt 以及任意一個 else-stmtstmt 結尾點(如果沒有 else 子句)的控制流轉移上是明確賦值的;
  • 如果 v 在 expr 結尾處的狀態是「在 true 表達式之后明確賦值」,那么在指向 then-stmt 的控制流轉移上是明確賦值的,但指向 else-stmtstmt 的結尾點(如果沒有 else 子句)的控制流轉移上是未明確賦值的;
  • 如果 v 在 expr 結尾點的狀態是「在 false 表達式之后明確賦值」,那么在指向 else-stmt 的控制流轉移上是明確賦值的,但指向 then-stmt 的控制流轉移上是未明確賦值的。位于 stmt 結束點(當且僅當在 then-stmt 結尾點是明確賦值的)上是明確賦值的。
  • 否則的話,位于指向任意一個 then-stmt、else-stmtstmt 結尾點(如果沒有 else 子句)的控制流轉移上的 v 被視作未明確賦值。

switch 語句

在帶有控制表達式 expr 的 switch 語句 stmt

  • 位于 expr 開始位置的 v 的明確賦值狀態與位于 stmt 開頭位置的 v 的狀態是一致的;
  • 在指向一個可訪問(reachable)的 switch 語句塊列表的控制流轉移上 v 明確賦值狀態就是 expr 結尾處的明確賦值狀態。

while 語句

對于形如以下的 while 語句 stmt

while ( expr ) while-body
  • 位于 expr 開頭位置的 v 的明確賦值狀態與 stmt 開頭處的一致;
  • 如果 v 在 expr 結尾處是明確賦值的,那么在指向 while-body 的控制流轉移上以及在 stmt 結尾點上的狀態是明確賦值的;
  • 如果 v 在 expr 結尾點的狀態是「在 true 表達式之后明確賦值」,那么在指向 while-body 的控制流轉移上它是明確賦值的,但在 stmt 結尾點上是未明確賦值的;
  • 如果 v 在 expr 結尾點的狀態是「在 false 表達式之后明確賦值」,那么在指向 stmt 結尾點的控制流轉移上它是明確賦值的,單位指向 while-body 的控制流轉移上它未明確賦值的。

do 語句

do 語句的明確賦值檢查有以下形式:

do do-body while ( expr ) ;
  • 位于 stmt 開頭處到 do-body 的控制流轉移(control flow transfer)上的 v 的明確賦值狀態與 stmt 開頭處的一致。
  • 位于 expr 開頭處的 v 的明確賦值狀態與 do-body 結尾處的一致。
  • 如果位于 expr 結尾處 v 是明確賦值的,那么在 stmt 結尾處的控制硫轉移上的 v 也是明確賦值的。
  • 如果位于 expr 結尾處 v 具有「在 false 表達式之后明確賦值」,那么在 stmt 結尾處的控制硫轉移上的 v 也是明確賦值的。

for 語句

for 語句的明確賦值檢查有以下形式:

for ( for-initializer ; for-condition ; for-iterator ) embedded-statement

如下面所寫語句一樣:

{    for-initializer ;    while ( for-condition ) {        embedded-statement ;        for-iterator ;    }}

如果 for-condition 從語句中省略,則當評估明確賦值狀態時,可將上述展開語句中的 for-condition 當做 true。

break、continue 與 goto 語句

break、continuegoto 語句導致的控制流轉移(control flow transfer)上 v 的明確賦值狀態與語句開始處 v 的明確賦值狀態一致。

throw 語句

對于以下形式的語句 stmt

throw expr ;

位于 expr 開頭處 v 的明確賦值狀態與 stmt 開頭處 v 的狀態一致。

return 語句

對于以下形式的語句 stmt

return expr ;
  • 位于 expr 開頭 v 的明確賦值狀態與 stmt 開頭 v 的狀態是一致的。
  • 如果 v 是輸出形參,則其必須明確賦值(二選一):
    • 要么在 expr 之后;
    • 要么在閉包于 return 語句的 try-finallytry-catch-finallyfinally 塊的結尾處。

對于以下形式的語句 stmt

return ;
  • 如果 v 是輸出形參,則其必須明確賦值(二選一):
    • 要么在 stmt 之前;
    • 要么在閉包于 return 語句的 try-catchtry-catch-finallyfinally 塊的結尾處。

try-catch 語句

對于以下形式的語句 stmt

try try-blockcatch(...) catch-block-1...catch(...) catch-block-n
  • 位于 try-block 開始處的 v 的明確賦值狀態與 stmt 開頭處一致;
  • 位于 catch-block-i 開始處(對于任意 i)的 v 的明確賦值狀態與 stmt 開頭處一致;
  • 當且僅當 v 位于 try-block 結尾點和每一個 catch-block-i(i ∈ [1, n])的結尾點是明確賦值的,則位于 stmt 結尾點的 v 的明確賦值狀態是明確賦值的。

try-finally 語句

對于以下形式的 try 語句 stmt

try try-block finally finally-block
  • 位于 try-block 開始處的 v 的明確賦值狀態與 stmt 開頭處一致;
  • 位于 finally-block 開始處的 v 的明確賦值狀態與 stmt 開頭處一致;
  • 當且僅當至少滿足以下一條條件時,位于 stmt 結尾點的 v 的明確賦值狀態是明確賦值的:
    • v 在 try-block 結束點是明確賦值的;
    • v 在 finally-bolck 結束點是明確賦值的。

如果控制流轉移(比方說,一個 goto 語句)從 try-block 內開始,結束于 try-block 外,那么如果 v 在 finally-block 的結束點上明確賦值,在控制流轉移上 v 同樣被視作明確賦值的(這不是必要條件,如果 v 在 finally-block 結束點上是明確賦值的,那么它任被視作明確賦值)。

try-catch-finally 語句

對于形如下面這段 try-catch-finally 的明確賦值分析

try try-block catch(...) catch-block-1...catch(...) catch-block-nfinally finally-block

與將 try-catch 語句閉包于 try-finally 內的效果一樣:

try {    try try-block     catch(...) catch-block-1    ...    catch(...) catch-block-n}finally finally-block

下例演示了明確賦值在不同 try 語句塊(第八章第十節)中的效果。

class A{    static void F() {        int i, j;        try {            goto LABEL;            // i 和 j 都沒有明確賦值            i = 1;            // i 明確賦值        }        catch {            // i 和 j 都沒有明確賦值            i = 3;            // i 明確賦值        }        finally {            // i 和 j 都沒有明確賦值            j = 5;            // j 明確賦值        }        // i and j 明確賦值        LABEL:;        // j 明確賦值    }}

foreach 語句

對于以下形式的 foreach 語句 stmt

foreach ( type identifier in expr ) embedded-statement
  • 位于 expr 開頭處的 v 的明確賦值狀態與 stmt 開頭處的一致;
  • 位于指向 embedded-statement 的控制流轉移上的 v 的明確賦值狀態與 expr 結尾處的一致。

using 語句

對于以下形式的 using 語句 stmt

using ( resource-acquisition ) embedded-statement
  • 位于 resource-acquisition 開頭處的 v 的明確賦值狀態與 stmt 開頭處的一致;
  • 位于指向 embedded-statement 的控制流轉移上的 v 的明確賦值狀態與 resource-acquisition 結尾處的一致。

lock 語句

對于以下形式的 lock 語句 stmt

lock ( expr ) embedded-statement
  • 位于 expr 開頭處的 v 的明確賦值狀態與 stmt 開頭處的一致;
  • 位于指向 embedded-statement 的控制流轉移上的 v 的明確賦值狀態與 expr 結尾處的一致。

yield 語句

對于以下形式的 yield return 語句 stmt

yield return expr ;
  • 位于 expr 開頭 v 的明確賦值狀態與 stmt 開頭 v 的狀態是一致的。
  • 位于 stmt 結尾 v 的明確賦值狀態與 expr 結尾 v 的狀態是一致的。

yield break 語句對于明確定義狀態沒有影響。

簡單表達式的一般規則

以下規則可應用于下諸類型之表達式:文本(literals,第七章第 6.1 節)、簡單名稱(simple names,第七章第 6.2 節)、成員訪問表達式(member access expressions,第七章第 6.4 節)、非索引基訪問表達式(non-indexed base access expressions,第七章第 6.8 節)、typeof 表達式(typeof expressions,第七章第 6.11 節)以及默認值表達式(default value expressions,第七章第 6.13 節)。

  • 位于上述表達式結尾處 v 的明確賦值狀態與位于表達式開頭的 v 的狀態一致。

帶嵌入表達式的表達式一般規則

以下規則可應用于下諸類型之表達式:帶括號的表達式(parenthesized expressions,第七章第 6.3 節)、元素訪問表達式(element access expressions,第七章第 6.6 節)、帶索引的基訪問表達式(base access expressions with indexing,第七章第 6.8 節)、增量與減量表達式(increment and decrement expressions,第七章第 6.9 節)、強制轉換表達式(cast expressions,第七章第 7.6 節)、一元 +, -, ~, * 表達式、二元 +, -, *, /, %, <<, >>, <, <=, >, >=, ==, !=, is, as, &, |, ^ 表達式(第七章第 8、9、10、11 節)、復合賦值表達式(compound assignment expressions, 第七章第 17.2 節)、checkedunchecked 表達式(第七章第 6.12 節)以及數組與委托創建表達式(array and delegate creation expressions,第七章第 6.10 節)。

這些表達式包含一個或多個固定順序無條件計算(unconditionally evaluated in a fixed order)的子表達式(sub-expressions)。比方說,二元運算符 % 先運算左邊的值,然后運算右邊的。索引操作先計算索引表達式(indexed expression),然后從左到右運算每個索引表達式(index expressions)。對于具有子表達式 expr1、expr2、……、exprn 的表達式 expr,按下列順序執行:

  • 位于 expr1 開頭的 v 的明確賦值狀態與 expr 開頭的狀態一致;
  • 位于 expri(i 大于 1) 開頭的 v 的明確賦值狀態與 exprn 結尾處 v 的狀態一致;
  • 位于 expr` 結尾處 v 的明確賦值狀態與 exprn 結尾處 v 的狀態一致。

調用表達式與對象創建表達式

對于以下形式的調用表達式(invocation expression)expr

primary-expression ( arg1 , arg2 , … , argn )

或以下形式的對象創建表達式(object creation expression):

new type ( arg1 , arg2 , … , argn )
  • 對于調用表達式,位于 primary-expression 前 v 的明確賦值狀態與 expr 前 v 的狀態一致。
  • 對于調用表達式,位于 arg1 之前 v 的明確賦值狀態與 primary-expression 后 v 的狀態是一致的。
  • 對于對象創建表達式,位于 arg1 之前 v 的明確賦值狀態與 expr 后 v 的狀態是一致的。
  • 對于每個 argi 實參,位于 argi 之后 v 的明確賦值狀態是由標準表達式規則(normal expression rules)所決定的,其中忽略所有的 refout 修飾符。
  • 對于每個 argi 實參(i 大于 1),位于 argi 之前 v 的明確賦值狀態與 argi-1 后 v 的狀態是一致的。
  • 如果變量 v 以輸出參數(形如 out v)的方式傳入實參,則 expr 后 v 的狀態是明確賦值的。否則的話,expr 后 v 的狀態與 argn 后 v 的狀態一致。
  • 對于數組初始化器(array initializers,第七章第 6.10.4 節)、對象初始化器(object initializers,第七章第 6.10.2 節)、集合初始化器(collection initializers,第七章第 6.10.3 節)以及匿名對象初始化器(anonymous object initializers,第七章第 6.10.6 節),它們的明確賦值狀態取決于定義這些構造所依據的擴展所決定。

簡單賦值表達式

對于形如 w = expr-rhs 的表達式 expr

  • expr-rhs 之前的 v 的明確賦值狀態與在 expr 前 v 的明確賦值狀態是一樣的。
  • 如果 w 是與 v 是同一變量,則 expr 之后的 v 的明確賦值狀態為「已被明確扶植」。否則 expr 之后的 v 的明確賦值狀態與 expr-rhs 之后的 v 的明確賦值狀態是一樣的。

&& 表達式

對于形如 expr-first && expr-second 的表達式 expr

  • expr-first 之前的 v 的明確賦值狀態與在 expr 之前的 v 的明確賦值狀態是一樣的。
  • 如果 expr-first 之后的 v 是明確賦值的或「在 true 表達式之后明確賦值」,那么在 expr-second 之前的 v 的明確賦值狀態是明確賦值的。否則,它就不是明確賦值的。
  • expr 之后的 v 的明確賦值狀態取決于:
    • 如果 expr-first 是值為 false 的常量表達式,則 expr 之后的 v 的明確賦值狀態與在 expr-first 之后的 v 的狀態是一樣的。
    • 不然的話,如果 expr-first 之后的 v 的狀態是明確賦值的,那么 expr 之后的 v 的狀態也是明確賦值的。
    • 再不然,如果 expt-second 之后的 v 的狀態是明確賦值的、并且 expr-first 之后的狀態是「在 false 表達式之后明確賦值」,那么 expr 之后的 v 的狀態是已明確賦值的。
    • 否則,如果 expr-second 后的 v 的狀態是明確賦值或「在 true 表達式之后明確賦值」,那么 expr 之后 v 的狀態是「在 true 表達式之后明確賦值」。
    • 再不然,如果 expr-first 后 v 的狀態是「在 false 表達式之后明確賦值」且 expr-second 后 v 的狀態是「在 false 表達式之后明確賦值」,那么 expr 的 v 的狀態是「在 false 表達式之后明確賦值」。
    • 否則,expr 之后的 v 的狀態就是未明確賦值了。

在下例中

class A{    static void F(int x, int y) {        int i;        if (x >= 0 && (i = y) >= 0) {            // i 明確賦值        }        else {            // i 沒有明確賦值        }        // i 沒有明確賦值    }}

變量 i 在 if 語句的其中一個嵌入語句中被視作是明確賦值的,但在另一個則不是。在方法 F 的 if 語句中,變量 i 在第一個嵌入語句中被明確賦值,因為在表達式 (i = y) 執行的時間先于這段嵌入語句的執行時間。相反,變量 i 在第二個嵌入語句中是未明確賦值的,因為 x >= 0 為 false 時的結果是變量 i 未被賦值。

|| 表達式

對于形如 expr-first || expr-second 的表達式 expr

  • expr-first 前 v 的明確賦值狀態與 expr 前 v 的狀態是一樣的。
  • 如果 expr-first 后 v 的狀態是明確賦值或「在 false 表達式之后明確賦值」,那么在 expr-second 前 v 的狀態是已明確賦值的。否則的話,他就是未明確賦值的。
  • expr 后 v 的明確賦值狀態取決于:
    • 如果 expr-first 是值為 true 的常量表達式,則 expr 之后的 v 的明確賦值狀態與在 expr-first 之后的 v 的狀態是一樣的。
    • 不然的話,如果 expr-first 之后的 v 的狀態是明確賦值的,那么 expr 之后的 v 的狀態也是明確賦值的。
    • 再不然,如果 expt-second 之后的 v 的狀態是明確賦值的、并且 expr-first 之后的狀態是「在 true 表達式之后明確賦值」,那么 expr 之后的 v 的狀態是已明確賦值的。
    • 否則,如果 expr-second 后的 v 的狀態是明確賦值或「在 false 表達式之后明確賦值」,那么 expr 之后 v 的狀態是「在 false 表達式之后明確賦值」。
    • 再不然,如果 expr-first 后 v 的狀態是「在 true 表達式之后明確賦值」且 expr-second 后 v 的狀態是「在 true 表達式之后明確賦值」,那么 expr 的 v 的狀態是「在 true 表達式之后明確賦值」。
    • 否則,expr 之后的 v 的狀態就是未明確賦值了。

在下例中

class A{    static void G(int x, int y) {        int i;        if (x >= 0 || (i = y) >= 0) {            // i 沒有明確賦值        }        else {            // i 明確賦值        }        // i 沒有明確賦值    }}

變量 i 在其中一個嵌入語句中被視作明確賦值,而在另一個中則不是。在方法 G 的 if 語句中,變量 i 在第二個嵌入語句中被視作明確賦值,因為表達式 (i = y) 的執行將先于這段嵌入語句。與此相反,變量 i 在第一個嵌入語句中被視作未明確賦值,因為 x >= 0 可能為 true,那么作為其結果變量 i 沒有被賦值。

! 表達式

對于形如 ! expr-operand 的表達式 expr

  • expr-operand 前 v 的明確賦值狀態與 expr 前 v 的狀態是一樣的。
  • expr 后 v 的明確賦值狀態取決于:
    • 如果 expr-operand 后 v 的狀態是已明確賦值的,那么 expr 后 v 的狀態是已明確賦值的
    • 如果 expr-operand 后 v 的狀態是未明確賦值的,那么 expr 后 v 的狀態是未明確賦值的
    • 如果 expr-operand 后 v 的狀態是「在 false 表達式后明確賦值」,那么 expr 后 v 的狀態是「在 true 表達式后明確賦值」。
    • 如果 expr-operand 后 v 的狀態是「在 true 表達式后明確賦值」,那么 expr 后 v 的狀態是「在 false 表達式后明確賦值」。

?? 表達式

對于形如 expr-first ?? expr-second 的表達式 expr

  • expr-first 前 v 的明確賦值狀態與 expr 前 v 的狀態是一樣的。
  • expr-second 前 v 的明確賦值狀態與 expr-first 后 v 的狀態是一樣的。
  • expr 后 v 的明確賦值狀態取決于:
    • expr-first 是值為 null 的常量表達式(第七章第十九節),則 expr 后 v 的狀態與 expr-second 后 v 的狀態是一致的。
    • 否則的話,expr 后 v 的狀態與 expr-first 后 v 的明確賦值狀態一致。

?: 表達式

對于形如 expr-cond ? expr-true : expr-false 的表達式 expr

  • expr-cond 前 v 的明確賦值狀態與 expr 前 v 的狀態是一樣的。
  • 當且僅當滿足以下一條時,在 expr-true 前 v 的明確賦值狀態是已明確賦值的:
    • expr-cond 是值為 false 的常量表達式。
    • expr-cond 后 v 的狀態是以明確賦值或「在 true 表達式后明確賦值」。
  • 當且僅當滿足以下一條時,在 expr-false 前 v 的明確賦值狀態是已明確賦值的:
    • expr-cond 是值為 true 的常量表達式。
    • expr-cond 后 v 的狀態是以明確賦值或「在 false 表達式后明確賦值」。(注:原文此處有筆誤)
  • expr 后 v 的明確賦值狀態取決于:
    • expr-cond 是值為 true 的常量表達式(第七章第十九節),則 expr 后 v 的狀態與 expr-true 后 v 的狀態一致。
    • 不然,若 expr-cond 是值為 false 的常量表達式(第七章第十九節),則 expr 后 v 的狀態與 expr-false 后 v 的狀態一致。
    • 再不然,若 expr-true 后 v 的狀態是明確賦值,且 expr-false 后 v 的狀態也是明確賦值的,則 expr 后 v 的狀態同樣是明確賦值的。
    • 否則,expr 之后的 v 的狀態就是未明確賦值了。

匿名函數

對于具有主體(塊或表達式)的 Lambda 表達式(lambda-expression)或匿名方法表達式(anonymous-method-expression)expr 的主體(body):

  • body 之前的外部變量 v 的明確賦值狀態與 expr 之前的 v 的狀態是一樣的。也就是說,外部變量的明確賦值狀態繼承自匿名函數上下文。
  • expr 之后的外部變量 v 的明確賦值狀態與 expr 之前的 v 的狀態是一樣的。

舉例

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

由于在匿名函數被聲明的時候 max 沒有明確賦值,所以這將產生一個「編譯時錯誤」。舉個例子。

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

由于在匿名函數之外對匿名函數內部的 n 進行明確賦值是沒有效果的,所以這同樣會產生一個「編譯時錯誤」。


變量引用

變量引用(variable-reference)是一個被歸類到變量(variable)的表達式(expression)。變量引用表示一個存儲空間,通過訪問它可以獲取當前值、保存新值。

variable-reference:    expression

在 C 和 C++ 中,變量引用(variable-reference)中稱為 lvalue。


變量引用的原子性

讀寫以下數據類型是原子性的(atomic):bool、 char、 byte、 sbyte、 shortushort、 uint、 int、 float 以及引用類型。另外,如果枚舉的基礎類型屬于上述列表內的,則讀寫該枚舉值也是原子性的。讀寫其它類型,包括 long、 ulong、 double、 decimal 以及用戶自定義的類型時,不能保證一定是原子的。除專門為該墓地設計的庫函數以外,對于增量(increment)或減量(decrement)這種情況,依舊不能保證原子性的讀取、修改與寫入(read-modify-write)。


[1]ARC:Automatic Reference Counting,自動引用計數,是開發程序時的一個編譯級別的特性,用于自動內存管理。更多請訪問此處以及此處。

__EOF__

C# Language Specification 5.0 翻譯計劃


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产97免费视| 国产精品激情自拍| 精品国产乱码久久久久酒店| 色在人av网站天堂精品| 亚洲激情在线观看| 欧美在线一级va免费观看| 日韩欧美在线免费观看| 国产成人91久久精品| 亚洲色图av在线| 日韩亚洲欧美成人| 中文字幕一区二区三区电影| 欧美精品久久久久a| 日韩在线欧美在线国产在线| 国产一区二区美女视频| 久久深夜福利免费观看| 国产视频亚洲视频| 成人黄色免费网站在线观看| 欧美成aaa人片在线观看蜜臀| 欧美韩国理论所午夜片917电影| 国产精品99久久久久久www| 欧美成人亚洲成人日韩成人| 欧美影院久久久| 欧美日韩免费观看中文| 日本久久久久久| 国产视频精品va久久久久久| 国产精品久久久久久久久男| 精品久久久久国产| 亚洲精品91美女久久久久久久| 久久久综合av| 亚洲精品久久久久久久久| 成人黄色大片在线免费观看| 欧美视频二区36p| 欧美视频精品一区| 蜜臀久久99精品久久久无需会员| 亚洲男人av电影| 亚洲白虎美女被爆操| 亚洲一区二区三区xxx视频| 九九热精品在线| 国产精品久久久久久久久久99| 中文字幕一区电影| 一本色道久久综合狠狠躁篇怎么玩| 亚洲最大福利视频| 日韩成人在线电影网| 亚洲国产日韩欧美综合久久| 国产日本欧美一区二区三区在线| 国产精品一区=区| 亚洲一区二区久久久| 91精品国产自产在线老师啪| 中文字幕国产亚洲2019| 国产精品一久久香蕉国产线看观看| 日韩av快播网址| 欧美亚洲伦理www| 久久精品91久久香蕉加勒比| 欧美日韩午夜视频在线观看| 亚洲精品videossex少妇| 日韩经典中文字幕在线观看| 日韩精品久久久久| 久久久久久97| 日韩国产高清视频在线| 久久激情视频久久| 91精品久久久久久久久久另类| www日韩欧美| 91在线精品播放| 亚洲性猛交xxxxwww| 国产精品国产三级国产aⅴ浪潮| 亚洲精品成人久久久| 亚洲精品久久在线| 2020国产精品视频| 欧美成人精品在线观看| 亚洲精品欧美日韩| 午夜精品一区二区三区在线播放| 欧美猛交ⅹxxx乱大交视频| 91成人福利在线| 久久久精品视频成人| 国产美女直播视频一区| 亚洲欧洲国产一区| www日韩欧美| 国产欧美日韩综合精品| 日韩久久精品电影| 色综合五月天导航| 久久久999国产| 欧美在线观看网址综合| 亚洲欧美在线第一页| 日本精品视频在线播放| 亚洲国产精品999| 自拍亚洲一区欧美另类| 欧美日韩免费区域视频在线观看| 久久久中文字幕| 亚洲高清色综合| 亚洲精品视频中文字幕| 亚洲精品中文字| 国产成人精品在线播放| 亚洲综合社区网| 国产suv精品一区二区| 91视频8mav| 欧美性xxxx18| 国产精品极品美女在线观看免费| 一区二区三区高清国产| 国产精品福利无圣光在线一区| 亚洲精品国精品久久99热一| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲欧美资源在线| 91色琪琪电影亚洲精品久久| 日本中文字幕成人| 欧美一区第一页| 亚洲电影在线观看| 国产精品 欧美在线| 成人免费网站在线| 7777kkkk成人观看| 亚洲国产成人久久综合| 国产成人小视频在线观看| 午夜精品一区二区三区在线播放| 92版电视剧仙鹤神针在线观看| 亚洲色图欧美制服丝袜另类第一页| 欧美性资源免费| 国模视频一区二区| 激情成人中文字幕| 成人激情视频在线播放| 中文字幕国产精品久久| 亚洲一区亚洲二区| 久热国产精品视频| 亚洲成年网站在线观看| 国产成人+综合亚洲+天堂| 伊人伊成久久人综合网小说| 欧美一区三区三区高中清蜜桃| 欧美精品在线播放| 超在线视频97| 中文字幕国产精品| 久久精品电影网站| 在线成人激情黄色| 国产噜噜噜噜久久久久久久久| 日韩欧美中文第一页| 国产精品久久久久久久久久东京| 成人动漫网站在线观看| 亚洲精品一区二三区不卡| 色偷偷亚洲男人天堂| 欧美日韩美女在线| 97在线免费观看视频| 国产在线视频91| 黑人巨大精品欧美一区二区| 欧美黄色性视频| 色噜噜狠狠狠综合曰曰曰88av| 91高清免费在线观看| www.久久久久久.com| 久久久91精品| 韩国视频理论视频久久| 国产精品极品尤物在线观看| 国产乱人伦真实精品视频| 国产又爽又黄的激情精品视频| 成人美女av在线直播| 在线播放国产一区二区三区| 亚洲精品资源美女情侣酒店| 深夜福利国产精品| 成人在线一区二区| 欧美乱大交做爰xxxⅹ性3| 性欧美亚洲xxxx乳在线观看| 91久久久久久久久久久| 亚洲欧美综合区自拍另类| 国产精品mp4| 亚洲伊人成综合成人网| 精品视频在线导航| 日本精品久久电影| 欧美午夜片欧美片在线观看| 三级精品视频久久久久|