# 運算式Expressions

## 運算式分類Expression classifications

• 值。A value. 每個值都有關聯型別。Every value has an associated type.
• 變數。A variable. 每個變數都有相關聯的類型，也就是變數的宣告型別。Every variable has an associated type, namely the declared type of the variable.
• 命名空間。A namespace. 具有此分類的運算式只能出現在 member_access (成員存取) 的左邊。An expression with this classification can only appear as the left hand side of a member_access (Member access). 在任何其他內容中，分類為命名空間的運算式會導致編譯階段錯誤。In any other context, an expression classified as a namespace causes a compile-time error.
• 類型。A type. 具有此分類的運算式只能出現在 member_access (成員存取) 的左邊，或做為運算子的運算元 as (as 運算子) 、 is 運算子 (is 運算子) 或 typeof 運算子 (typeof 運算子) 。An expression with this classification can only appear as the left hand side of a member_access (Member access), or as an operand for the as operator (The as operator), the is operator (The is operator), or the typeof operator (The typeof operator). 在任何其他內容中，分類為類型的運算式會導致編譯時期錯誤。In any other context, an expression classified as a type causes a compile-time error.
• 方法群組，這是成員查閱 (成員查閱) 所產生的一組多載方法。A method group, which is a set of overloaded methods resulting from a member lookup (Member lookup). 方法群組可以有相關聯的實例運算式和關聯的型別引數清單。A method group may have an associated instance expression and an associated type argument list. 叫用實例方法時，評估實例運算式的結果會成為 this (此存取) 所代表的實例。When an instance method is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access). Invocation_expression 的 (調用運算式中允許方法群組) 、 delegate_creation_expression (委派建立運算式) 和做為運算子的左邊，並且可以隱含地轉換為相容的委派類型 (方法群組轉換) 。A method group is permitted in an invocation_expression (Invocation expressions) , a delegate_creation_expression (Delegate creation expressions) and as the left hand side of an is operator, and can be implicitly converted to a compatible delegate type (Method group conversions). 在任何其他內容中，分類為方法群組的運算式會導致編譯時期錯誤。In any other context, an expression classified as a method group causes a compile-time error.
• Null 常值。A null literal. 具有此分類的運算式可以隱含地轉換成參考型別或可為 null 的型別。An expression with this classification can be implicitly converted to a reference type or nullable type.
• 匿名函式。An anonymous function. 具有此分類的運算式可以隱含地轉換成相容的委派類型或運算式樹狀架構類型。An expression with this classification can be implicitly converted to a compatible delegate type or expression tree type.
• 屬性存取。A property access. 每個屬性存取都有相關聯的類型，也就是屬性的型別。Every property access has an associated type, namely the type of the property. 此外，屬性存取可能會有相關聯的實例運算式。Furthermore, a property access may have an associated instance expression. 當叫用存取子 get (set 實例屬性存取的或區塊) 時，評估實例運算式的結果會變成 this (此存取) 所代表的實例。When an accessor (the get or set block) of an instance property access is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access).
• 事件存取。An event access. 每個事件存取都有相關聯的類型，也就是事件的類型。Every event access has an associated type, namely the type of the event. 此外，事件存取可能會有相關聯的實例運算式。Furthermore, an event access may have an associated instance expression. 事件存取可能會顯示為和運算子的左運算元 +=-= (事件指派) 。An event access may appear as the left hand operand of the += and -= operators (Event assignment). 在任何其他內容中，分類為事件存取權的運算式會導致編譯時期錯誤。In any other context, an expression classified as an event access causes a compile-time error.
• 索引子存取。An indexer access. 每個索引子存取都有相關聯的類型，也就是索引子的元素類型。Every indexer access has an associated type, namely the element type of the indexer. 此外，索引子存取有相關聯的實例運算式和相關聯的引數清單。Furthermore, an indexer access has an associated instance expression and an associated argument list. 在叫 get set 用索引子存取 (或區塊) 的存取子時，評估實例運算式的結果會變成 this (此存取) 所表示的實例，而評估引數清單的結果會變成叫用的參數清單。When an accessor (the get or set block) of an indexer access is invoked, the result of evaluating the instance expression becomes the instance represented by this (This access), and the result of evaluating the argument list becomes the parameter list of the invocation.
• 不做任何動作。Nothing. 當運算式是傳回型別為的方法調用時，就會發生這種情況 voidThis occurs when the expression is an invocation of a method with a return type of void. 分類為 nothing 的運算式只在 statement_expression (運算式語句) 的內容中有效。An expression classified as nothing is only valid in the context of a statement_expression (Expression statements).

### 運算式的值Values of expressions

• 變數的值只是目前儲存在變數所識別之儲存位置的值。The value of a variable is simply the value currently stored in the storage location identified by the variable. 變數必須被視為明確指派 (明確 指派) ，才能取得其值，否則就會發生編譯時期錯誤。A variable must be considered definitely assigned (Definite assignment) before its value can be obtained, or otherwise a compile-time error occurs.
• 藉由叫用屬性的 get 存取 子，即可取得屬性存取運算式的值。The value of a property access expression is obtained by invoking the get accessor of the property. 如果屬性沒有 get 存取 子，就會發生編譯階段錯誤。If the property has no get accessor, a compile-time error occurs. 否則，函式成員調用 (動態多載解析) 的編譯時間檢查 ，而且叫用的結果會成為屬性存取運算式的值。Otherwise, a function member invocation (Compile-time checking of dynamic overload resolution) is performed, and the result of the invocation becomes the value of the property access expression.
• 索引子存取運算式的值是透過叫用索引子的 get 存取 子取得。The value of an indexer access expression is obtained by invoking the get accessor of the indexer. 如果索引子沒有 get 存取 子，就會發生編譯時期錯誤。If the indexer has no get accessor, a compile-time error occurs. 否則，會使用與索引子存取運算式相關聯的引數清單來執行動態多載解析) 的函數成員調用 (編譯時間檢查 ，而且叫用的結果會成為索引子存取運算式的值。Otherwise, a function member invocation (Compile-time checking of dynamic overload resolution) is performed with the argument list associated with the indexer access expression, and the result of the invocation becomes the value of the indexer access expression.

## 靜態和動態繫結Static and Dynamic Binding

C # 中的下列作業受限於系結：The following operations in C# are subject to binding:

• 成員存取： e.MMember access: e.M
• 方法調用： e.M(e1, ..., eN)Method invocation: e.M(e1, ..., eN)
• 委派調用：e(e1, ..., eN)Delegate invocation:e(e1, ..., eN)
• 元素存取： e[e1, ..., eN]Element access: e[e1, ..., eN]
• 物件建立： new C(e1, ..., eN)Object creation: new C(e1, ..., eN)
• 多載一元運算子： +-!~ 、、、 ++ -- truefalseOverloaded unary operators: +, -, !, ~, ++, --, true, false
• 多載的二元運算子： +-*/%&&& 、、 | ||?? ^ << >> == != > < >= 、、、、、、、、、、、、、、、、、 <=Overloaded binary operators: +, -, *, /, %, &, &&, |, ||, ??, ^, <<, >>, ==,!=, >, <, >=, <=
• 指派運算子： =+=-=*=/=%=&=|=^=<<=>>=Assignment operators: =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
• 隱含和明確轉換Implicit and explicit conversions

### 系結時間Binding-time

object  o = 5;
dynamic d = 5;

Console.WriteLine(5);  // static  binding to Console.WriteLine(int)
Console.WriteLine(o);  // static  binding to Console.WriteLine(object)
Console.WriteLine(d);  // dynamic binding to Console.WriteLine(int)


### 組成運算式的類型Types of constituent expressions

• 編譯時間類型的組成運算式會被 dynamic 視為具有運算式在執行時間評估為的實際數值型別。A constituent expression of compile-time type dynamic is considered to have the type of the actual value that the expression evaluates to at runtime
• 編譯時間類型為型別參數的組成運算式，會被視為具有類型參數在執行時間系結的型別。A constituent expression whose compile-time type is a type parameter is considered to have the type which the type parameter is bound to at runtime
• 否則，會將組成運算式視為具有其編譯時間類型。Otherwise the constituent expression is considered to have its compile-time type.

## 運算子Operators

• 一元運算子。Unary operators. 一元運算子採用一個運算元，並使用前置標記法 (例如 --x) 或後置標記法 (例如 x++) 。The unary operators take one operand and use either prefix notation (such as --x) or postfix notation (such as x++).
• 二元運算子。Binary operators. 二元運算子採用兩個運算元，且全都使用中置標記法 (例如 x + y) 。The binary operators take two operands and all use infix notation (such as x + y).
• 三元運算子。Ternary operator. 只有一個三元運算子（ ?: ）存在; 它會採用三個運算元，並使用中綴標記法 (c ? x : y) 。Only one ternary operator, ?:, exists; it takes three operands and uses infix notation (c ? x : y).

### 運算子優先順序和關聯性Operator precedence and associativity

Null 聯合運算子The null coalescing operator Null 聯合Null coalescing ??

• 除了指派運算子和 null 聯合運算子之外，所有二元運算子都是 左方關聯 的，這表示作業是由左至右執行。Except for the assignment operators and the null coalescing operator, all binary operators are left-associative, meaning that operations are performed from left to right. 例如，x + y + z 會判斷值為 (x + y) + zFor example, x + y + z is evaluated as (x + y) + z.
• 指派運算子、null 聯合運算子和條件運算子 (?:) 是 右向關聯，這表示作業是由右至左執行。The assignment operators, the null coalescing operator and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. 例如，x = y = z 會判斷值為 x = (y = z)For example, x = y = z is evaluated as x = (y = z).

+   -   !   ~   ++   --   true   false


+   -   *   /   %   &   |   ^   <<   >>   ==   !=   >   <   >=   <=


op x operator op(x)
x op operator op(x)
x op y operator op(x,y)

• 針對作業所提供的候選使用者定義運算子集合 X operator op(x) ，是使用 候選使用者定義運算子的規則來決定。The set of candidate user-defined operators provided by X for the operation operator op(x) is determined using the rules of Candidate user-defined operators.
• 如果候選的使用者定義運算子集合不是空的，則這會成為作業的候選運算子集合。If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. 否則，預先定義的一元實 operator op 組（包括其提升形式）會成為作業的候選運算子集合。Otherwise, the predefined unary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. 指定運算子的預先定義的實 (主要運算式一元運算子) 指定于運算子的描述中。The predefined implementations of a given operator are specified in the description of the operator (Primary expressions and Unary operators).
• 多載解析的多載解析 規則會套用 至候選運算子集合，以選取與引數清單相關的最佳運算子 (x) ，而且這個運算子會成為多載解析程式的結果。The overload resolution rules of Overload resolution are applied to the set of candidate operators to select the best operator with respect to the argument list (x), and this operator becomes the result of the overload resolution process. 如果多載解析無法選取單一最佳運算子，則會發生系結階段錯誤。If overload resolution fails to select a single best operator, a binding-time error occurs.

• 由和針對作業所提供的候選使用者定義運算子集合 X Y operator op(x,y)The set of candidate user-defined operators provided by X and Y for the operation operator op(x,y) is determined. 此集合是由所提供之候選運算子的聯集 X 以及提供的候選運算子所組成 Y ，每個都是使用 候選使用者定義運算子的規則來決定。The set consists of the union of the candidate operators provided by X and the candidate operators provided by Y, each determined using the rules of Candidate user-defined operators. 如果 X 和是 Y 相同的型別，或者如果 XY 是衍生自通用基底型別，則共用的候選運算子只會在合併的集合中進行。If X and Y are the same type, or if X and Y are derived from a common base type, then shared candidate operators only occur in the combined set once.
• 如果候選的使用者定義運算子集合不是空的，則這會成為作業的候選運算子集合。If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. 否則，預先定義的二進位執行 operator op （包括其提升形式）會成為作業的候選運算子集合。Otherwise, the predefined binary operator op implementations, including their lifted forms, become the set of candidate operators for the operation. 指定運算子的預先定義的實作為透過條件式邏輯運算子) ，在運算子 (算術運算子的描述中指定。The predefined implementations of a given operator are specified in the description of the operator (Arithmetic operators through Conditional logical operators). 針對預先定義的列舉和委派運算子，唯一考慮的運算子是由列舉或委派型別所定義的運算子，也就是其中一個運算元的系結時間型別。For predefined enum and delegate operators, the only operators considered are those defined by an enum or delegate type that is the binding-time type of one of the operands.
• 多載解析的多載解析 規則會套用 至候選運算子集合，以選取與引數清單相關的最佳運算子 (x,y) ，而且這個運算子會成為多載解析程式的結果。The overload resolution rules of Overload resolution are applied to the set of candidate operators to select the best operator with respect to the argument list (x,y), and this operator becomes the result of the overload resolution process. 如果多載解析無法選取單一最佳運算子，則會發生系結階段錯誤。If overload resolution fails to select a single best operator, a binding-time error occurs.

### 候選的使用者定義運算子Candidate user-defined operators

• 判斷類型 T0Determine the type T0. 如果 T 是可為 null 的型別， T0 則為其基礎類型，否則 T0 等於 TIf T is a nullable type, T0 is its underlying type, otherwise T0 is equal to T.
• 針對中的所有宣告 operator op T0 和這類運算子的所有形式，如果至少有一個運算子適用 (適用 的函式成員) 與引數清單有關 A ，則候選運算子集會由中的所有這類適用運算子組成 T0For all operator op declarations in T0 and all lifted forms of such operators, if at least one operator is applicable (Applicable function member) with respect to the argument list A, then the set of candidate operators consists of all such applicable operators in T0.
• 否則，如果 T0object ，候選運算子的集合就會是空的。Otherwise, if T0 is object, the set of candidate operators is empty.
• 否則，所提供的候選運算子集會 T0 是的直接基類所提供的候選運算子集 T0T0 如果是型別參數，則為的有效基類 T0Otherwise, the set of candidate operators provided by T0 is the set of candidate operators provided by the direct base class of T0, or the effective base class of T0 if T0 is a type parameter.

### 數值升階Numeric promotions

int operator *(int x, int y);
uint operator *(uint x, uint y);
long operator *(long x, long y);
ulong operator *(ulong x, ulong y);
float operator *(float x, float y);
double operator *(double x, double y);
decimal operator *(decimal x, decimal y);


#### 二進位數值升級Binary numeric promotions

• 如果任一個運算元的類型為 decimal ，則會將另一個運算元轉換成類型 decimal ，如果另一個運算元的類型是或，就會發生系結階段錯誤 float doubleIf either operand is of type decimal, the other operand is converted to type decimal, or a binding-time error occurs if the other operand is of type float or double.
• 否則，如果任一個運算元的類型為 double ，則會將另一個運算元轉換成類型 doubleOtherwise, if either operand is of type double, the other operand is converted to type double.
• 否則，如果任一個運算元的類型為 float ，則會將另一個運算元轉換成類型 floatOtherwise, if either operand is of type float, the other operand is converted to type float.
• 否則，如果任一個運算元的類型為 ulong ，則會將另一個運算元轉換成類型 ulong ，如果另一個運算元的類型為 sbyteshort 、或，則會發生系結階段錯誤 int longOtherwise, if either operand is of type ulong, the other operand is converted to type ulong, or a binding-time error occurs if the other operand is of type sbyte, short, int, or long.
• 否則，如果任一個運算元的類型為 long ，則會將另一個運算元轉換成類型 longOtherwise, if either operand is of type long, the other operand is converted to type long.
• 否則，如果任一個運算元的類型為 uint ，而另一個運算元的類型為 sbyteshortint ，則這兩個運算元會轉換為類型 longOtherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long.
• 否則，如果任一個運算元的類型為 uint ，則會將另一個運算元轉換成類型 uintOtherwise, if either operand is of type uint, the other operand is converted to type uint.
• 否則，會將這兩個運算元轉換成類型 intOtherwise, both operands are converted to type int.

decimal AddPercent(decimal x, double percent) {
return x * (1.0 + percent / 100.0);
}


decimal AddPercent(decimal x, double percent) {
return x * (decimal)(1.0 + percent / 100.0);
}


### 提起運算子Lifted operators

• 針對一元運算子For the unary operators

+  ++  -  --  !  ~


如果運算元和結果型別都不是可為 null 的實值型別，則會有運算子的形式存在。a lifted form of an operator exists if the operand and result types are both non-nullable value types. 藉由將單一修飾詞加入 ? 至運算元和結果型別，即可建立產生的形式。The lifted form is constructed by adding a single ? modifier to the operand and result types. 如果運算元為 null，則提升運算子會產生 null 值。The lifted operator produces a null value if the operand is null. 否則，提起運算子會解除封裝運算元、套用基礎運算子，然後包裝結果。Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result.

• 二元運算子的For the binary operators

+  -  *  /  %  &  |  ^  <<  >>


如果運算元和結果型別都是不可為 null 的實值型別，則會有運算子的形式存在。a lifted form of an operator exists if the operand and result types are all non-nullable value types. 產生的形式是藉由將單一修飾詞加入 ? 至每個運算元和結果型別來構成。The lifted form is constructed by adding a single ? modifier to each operand and result type. 如果其中一或兩個運算元為 null，則會產生 null 值， (例外狀況 &| 類型的和運算子 bool? ，如 布林邏輯運算子) 中所述。The lifted operator produces a null value if one or both operands are null (an exception being the & and | operators of the bool? type, as described in Boolean logical operators). 否則，提起運算子會解除包裝運算元、套用基礎運算子，並包裝結果。Otherwise, the lifted operator unwraps the operands, applies the underlying operator, and wraps the result.

• 針對等號比較運算子For the equality operators

==  !=


如果運算元型別同時為不可為 null 的實值型別，且結果型別為，則會有運算子的形式存在 boola lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. 藉由將單一修飾詞加入 ? 至每個運算元類型，即可建立此形式。The lifted form is constructed by adding a single ? modifier to each operand type. 提起運算子會將兩個 null 值視為相等，而 null 值不會與任何非 null 值相等。The lifted operator considers two null values equal, and a null value unequal to any non-null value. 如果這兩個運算元都不是 null，則提升運算子會解除包裝運算元，並套用基礎運算子來產生 bool 結果。If both operands are non-null, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

• 針對關聯式運算子For the relational operators

<  >  <=  >=


如果運算元型別同時為不可為 null 的實值型別，且結果型別為，則會有運算子的形式存在 boola lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. 藉由將單一修飾詞加入 ? 至每個運算元類型，即可建立此形式。The lifted form is constructed by adding a single ? modifier to each operand type. false如果一個或兩個運算元都是 null，則提升運算子會產生值。The lifted operator produces the value false if one or both operands are null. 否則，提起運算子會解除包裝運算元，並套用基礎運算子來產生 bool 結果。Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

## 成員查詢Member lookup

N類型中具有類型參數之名稱的成員查閱 K    T 會以下列方式處理：A member lookup of a name N with K type parameters in a type T is processed as follows:

• 首先，會決定一組名為的可存取成員  NFirst, a set of accessible members named N is determined:
• 如果 T 是型別參數，則集合是  N 在指定為主要條件約束或次要條件約束的每個類型中，所命名之可存取成員集合的聯集  T ，以及中所命名的可存取成員集合) ( N objectIf T is a type parameter, then the set is the union of the sets of accessible members named N in each of the types specified as a primary constraint or secondary constraint (Type parameter constraints) for T, along with the set of accessible members named N in object.
• 否則，此集合會由中命名的所有可存取 (成員存取) 成員  N  T ，包括繼承的成員以及中所命名的可存取成員  N objectOtherwise, the set consists of all accessible (Member access) members named N in T, including inherited members and the accessible members named N in object. 如果 T 是一種結構化型別，則會藉由替代型別引數來取得成員集，如 結構化類型的成員中所述。If T is a constructed type, the set of members is obtained by substituting type arguments as described in Members of constructed types. 包含修飾詞的成員 override 將會從集合中排除。Members that include an override modifier are excluded from the set.
• 接下來，如果 K 是零，則會移除宣告包含類型參數的所有巢狀型別。Next, if K is zero, all nested types whose declarations include type parameters are removed. 如果不 K 是零，則會移除具有不同類型參數數目的所有成員。If K is not zero, all members with a different number of type parameters are removed. 請注意，如果 K 是零，則不會移除具有型別參數的方法，因為型別推斷程式 (型別推斷) 可能可以推斷型別引數。Note that when K is zero, methods having type parameters are not removed, since the type inference process (Type inference) might be able to infer the type arguments.
• 接下來，如果叫用 成員，則 會從集合中移除所有的非 >invocable 成員。Next, if the member is invoked, all non-invocable members are removed from the set.
• 接著，會從集合中移除其他成員隱藏的成員。Next, members that are hidden by other members are removed from the set. 針對集合中的每個成員 S.M ，其中是宣告成員的型別， S  M 則會套用下列規則：For every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied:
• 如果 M 是常數、欄位、屬性、事件或列舉成員，則基底類型中宣告的所有成員 S 都會從集合中移除。If M is a constant, field, property, event, or enumeration member, then all members declared in a base type of S are removed from the set.
• 如果 M 是型別宣告，則會從集合中移除基底類型中宣告的所有非型別 S ，而且具有與基底類型中宣告之相同類型參數數目的所有類型宣告， M S 都會從集合中移除。If M is a type declaration, then all non-types declared in a base type of S are removed from the set, and all type declarations with the same number of type parameters as M declared in a base type of S are removed from the set.
• 如果 M 是方法，則基底類型中宣告的所有非方法成員 S 都會從集合中移除。If M is a method, then all non-method members declared in a base type of S are removed from the set.
• 接下來，會從集合中移除類別成員隱藏的介面成員。Next, interface members that are hidden by class members are removed from the set. 只有當 T 是型別參數，而且 T 具有 object 非空白的有效介面集 (類型參數條件約束) 時，此步驟才會有作用。This step only has an effect if T is a type parameter and T has both an effective base class other than object and a non-empty effective interface set (Type parameter constraints). 針對集合中的每個成員 S.M ，其中 S 是宣告成員的類型 M ，如果是以外的類別宣告，則會套用下列規則 S objectFor every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied if S is a class declaration other than object:
• 如果 M 是常數、欄位、屬性、事件、列舉成員或型別宣告，則會從集合中移除在介面宣告中宣告的所有成員。If M is a constant, field, property, event, enumeration member, or type declaration, then all members declared in an interface declaration are removed from the set.
• 如果 M 是方法，則會從集合中移除介面宣告中宣告的所有非方法成員，並且會從集合中移除所有具有相同簽章的方法 MIf M is a method, then all non-method members declared in an interface declaration are removed from the set, and all methods with the same signature as M declared in an interface declaration are removed from the set.
• 最後，移除隱藏的成員之後，就會判斷查閱的結果：Finally, having removed hidden members, the result of the lookup is determined:
• 如果集合是由非方法的單一成員所組成，則這個成員是查閱的結果。If the set consists of a single member that is not a method, then this member is the result of the lookup.
• 否則，如果集合只包含方法，則此方法群組就是查閱的結果。Otherwise, if the set contains only methods, then this group of methods is the result of the lookup.
• 否則，查閱會不明確，而且會發生系結階段錯誤。Otherwise, the lookup is ambiguous, and a binding-time error occurs.

### 基底類型Base types

• 如果 Tobject ，則表示 T 沒有基底類型。If T is object, then T has no base type.
• 如果 Tenum_type，的基底類型 T 為類別類型 System.EnumSystem.ValueTypeobjectIf T is an enum_type, the base types of T are the class types System.Enum, System.ValueType, and object.
• 如果 Tstruct_type，的基底類型 T 為類別類型 System.ValueTypeobjectIf T is a struct_type, the base types of T are the class types System.ValueType and object.
• 如果 Tclass_type，的基底類型 T 就是的基類 T ，包括類別型別 objectIf T is a class_type, the base types of T are the base classes of T, including the class type object.
• 如果 Tinterface_type，的基底類型 T 為的基底介面 T 和類別類型 objectIf T is an interface_type, the base types of T are the base interfaces of T and the class type object.
• 如果 Tarray_type，的基底類型 T 為類別類型 System.ArrayobjectIf T is an array_type, the base types of T are the class types System.Array and object.
• 如果 Tdelegate_type，的基底類型 T 為類別類型 System.DelegateobjectIf T is a delegate_type, the base types of T are the class types System.Delegate and object.

## 函式成員Function members

• 方法Methods
• 屬性Properties
• 事件Events
• 索引子Indexers
• 使用者定義的運算子User-defined operators
• 實例的函式Instance constructors
• 靜態建構函式Static constructors
• 解構函式Destructors

T.F(x,y) 套用多載解析，以選取 F 類別或結構中的最佳方法 TOverload resolution is applied to select the best method F in the class or struct T. 如果方法不是，就會發生系結階段錯誤 staticA binding-time error occurs if the method is not static. 使用引數清單叫用方法 (x,y)The method is invoked with the argument list (x,y).
e.F(x,y) 使用多載解析來選取類別、結構或類型所提供之介面中的最佳方法 F eOverload resolution is applied to select the best method F in the class, struct, or interface given by the type of e. 如果方法為，就會發生系結階段錯誤 staticA binding-time error occurs if the method is static. 使用實例運算式 e 和引數清單叫用方法 (x,y)The method is invoked with the instance expression e and the argument list (x,y).

P = value set P 使用引數清單叫用包含類別或結構中之屬性的存取子 (value)The set accessor of the property P in the containing class or struct is invoked with the argument list (value). 如果是唯讀的，則會發生編譯時期錯誤 PA compile-time error occurs if P is read-only. 如果不 Pstatic ，則實例運算式為 thisIf P is not static, the instance expression is this.
T.P get P 類別或結構中叫用屬性的存取子 TThe get accessor of the property P in the class or struct T is invoked. 如果 P 不是 staticP 為唯讀，就會發生編譯時期錯誤。A compile-time error occurs if P is not static or if P is write-only.
T.P = value set P T 使用引數清單叫用類別或結構中屬性的存取子 (value)The set accessor of the property P in the class or struct T is invoked with the argument list (value). 如果 P 不是 static 或唯讀，就會發生編譯時期錯誤 PA compile-time error occurs if P is not static or if P is read-only.
e.P get P 類別、結構或型別中所指定之屬性的存取子 e 會以實例運算式叫用 eThe get accessor of the property P in the class, struct, or interface given by the type of e is invoked with the instance expression e. 如果 P 是或，則會發生系結階段錯誤 static PA binding-time error occurs if P is static or if P is write-only.
e.P = value set P e 使用實例運算式 e 和引數清單叫用之型別的類別、結構或介面中的屬性存取子 (value)The set accessor of the property P in the class, struct, or interface given by the type of e is invoked with the instance expression e and the argument list (value). 如果 P 為， static 或如果是唯讀的，則會發生系結階段錯誤 PA binding-time error occurs if P is static or if P is read-only.

E -= value remove E 用包含類別或結構中事件的存取子。The remove accessor of the event E in the containing class or struct is invoked. 如果不 E 是靜態的，則實例運算式為 thisIf E is not static, the instance expression is this.
T.E += value add E 用類別或結構中的事件存取子 TThe add accessor of the event E in the class or struct T is invoked. 如果不是靜態的，則會發生系結階段錯誤 EA binding-time error occurs if E is not static.
T.E -= value remove E 用類別或結構中的事件存取子 TThe remove accessor of the event E in the class or struct T is invoked. 如果不是靜態的，則會發生系結階段錯誤 EA binding-time error occurs if E is not static.
e.E += value add E 類別、結構或介面中的事件存取子 e 是使用實例運算式叫用的 eThe add accessor of the event E in the class, struct, or interface given by the type of e is invoked with the instance expression e. 如果是靜態的，則會發生系結階段錯誤 EA binding-time error occurs if E is static.
e.E -= value remove E 類別、結構或介面中的事件存取子 e 是使用實例運算式叫用的 eThe remove accessor of the event E in the class, struct, or interface given by the type of e is invoked with the instance expression e. 如果是靜態的，則會發生系結階段錯誤 EA binding-time error occurs if E is static.

e[x,y] = value 套用多載解析，以選取類別、結構或類型所提供之介面中的最佳索引子 eOverload resolution is applied to select the best indexer in the class, struct, or interface given by the type of e. set使用實例運算式 e 和引數清單叫用索引子的存取子 (x,y,value)The set accessor of the indexer is invoked with the instance expression e and the argument list (x,y,value). 如果索引子是唯讀的，則會發生系結階段錯誤。A binding-time error occurs if the indexer is read-only.

x + y 會套用多載解析，以在和類型所指定的類別或結構中選取最佳的二元運算子 x yOverload resolution is applied to select the best binary operator in the classes or structs given by the types of x and y. 使用引數清單叫用選取的運算子 (x,y)The selected operator is invoked with the argument list (x,y).

### 引數清單Argument lists

• 針對實例的函式、方法、索引子和委派，會將引數指定為 argument_list，如下所述。For instance constructors, methods, indexers and delegates, the arguments are specified as an argument_list, as described below. 針對索引子，當叫 set 用存取子時，引數清單會另外包含指定為指派運算子右運算元的運算式。For indexers, when invoking the set accessor, the argument list additionally includes the expression specified as the right operand of the assignment operator.
• 若為屬性，當叫用存取子時，引數清單是空的 get ，而且會包含在叫用存取子時，指定為指派運算子右運算元的運算式 setFor properties, the argument list is empty when invoking the get accessor, and consists of the expression specified as the right operand of the assignment operator when invoking the set accessor.
• 若為事件，引數清單是由指定為或運算子右運算元的運算式所組成 += -=For events, the argument list consists of the expression specified as the right operand of the += or -= operator.
• 如果是使用者定義的運算子，引數清單會包含一元運算子的單一運算元或二元運算子的兩個運算元。For user-defined operators, the argument list consists of the single operand of the unary operator or the two operands of the binary operator.

argument_list
: argument (',' argument)*
;

argument
: argument_name? argument_value
;

argument_name
: identifier ':'
;

argument_value
: expression
| 'ref' variable_reference
| 'out' variable_reference
;


Argument_list 是由一或多個 引數（以逗號分隔）所組成。An argument_list consists of one or more argument s, separated by commas. 每個引數都包含一個選擇性的 argument_name ，後面接著一個 argument_valueEach argument consists of an optional argument_name followed by an argument_value. 具有 argument_name引數 稱為 *具名引數 ，而 不含 argument_name 的引數 * 則是 *位置引數An argument with an argument_name is referred to as a named argument _, whereas an _argument without an argument_name is a *positional argument. 位置引數在 _argument_list * 中的具名引數後面出現錯誤。It is an error for a positional argument to appear after a named argument in an _argument_list*.

Argument_value 可以採用下列其中一種形式：The argument_value can take one of the following forms:

• 運算式，表示引數會以值參數的形式傳遞 (值參數) 。An expression, indicating that the argument is passed as a value parameter (Value parameters).
• 關鍵字 ref 後面接著 Variable_reference (變數參考) ，表示會將引數做為參考參數傳遞 (參考參數) 。The keyword ref followed by a variable_reference (Variable references), indicating that the argument is passed as a reference parameter (Reference parameters). 必須明確指派變數 (明確 指派) ，才能將變數作為參考參數來傳遞。A variable must be definitely assigned (Definite assignment) before it can be passed as a reference parameter. 關鍵字 out 後面接著 Variable_reference (變數參考) ，表示引數會以輸出參數的形式傳遞 (輸出參數) 。The keyword out followed by a variable_reference (Variable references), indicating that the argument is passed as an output parameter (Output parameters). 在變數作為輸出參數傳遞的函式成員調用之後，會將變數視為明確指派 (明確 指派) 。A variable is considered definitely assigned (Definite assignment) following a function member invocation in which the variable is passed as an output parameter.

#### 對應的參數Corresponding parameters

• 針對在類別中定義的虛擬方法和索引子，會從函式成員最特定的宣告或覆寫來挑選參數清單，從接收者的靜態類型開始，然後搜尋其基類。For virtual methods and indexers defined in classes, the parameter list is picked from the most specific declaration or override of the function member, starting with the static type of the receiver, and searching through its base classes.
• 針對介面方法和索引子，會挑選參數清單，形成最特定的成員定義，從介面類別型開始，然後搜尋基底介面。For interface methods and indexers, the parameter list is picked form the most specific definition of the member, starting with the interface type and searching through the base interfaces. 如果找不到唯一的參數清單，則會建立具有無法存取名稱且沒有選擇性參數的參數清單，讓調用無法使用具名引數或省略選擇性引數。If no unique parameter list is found, a parameter list with inaccessible names and no optional parameters is constructed, so that invocations cannot use named parameters or omit optional arguments.
• 若為部分方法，則會使用定義部分方法宣告的參數清單。For partial methods, the parameter list of the defining partial method declaration is used.
• 對於所有其他的函式成員和委派，只有單一參數清單，也就是使用的參數清單。For all other function members and delegates there is only a single parameter list, which is the one used.

• Argument_list 實例的函式、方法、索引子和委派的引數：Arguments in the argument_list of instance constructors, methods, indexers and delegates:
• 位置引數，在參數清單中相同位置的固定參數會與該參數相對應。A positional argument where a fixed parameter occurs at the same position in the parameter list corresponds to that parameter.
• 函式成員的位置引數，其以其正常形式叫用的參數陣列，會對應至參數陣列，此參數陣列必須在參數清單中的相同位置發生。A positional argument of a function member with a parameter array invoked in its normal form corresponds to the parameter array, which must occur at the same position in the parameter list.
• 函式成員的位置引數，該函式成員具有展開形式的參數陣列，而在參數清單中的相同位置沒有任何固定參數，則對應至參數陣列中的元素。A positional argument of a function member with a parameter array invoked in its expanded form, where no fixed parameter occurs at the same position in the parameter list, corresponds to an element in the parameter array.
• 具名引數會對應到參數清單中相同名稱的參數。A named argument corresponds to the parameter of the same name in the parameter list.
• 針對索引子， set 叫用存取子時，指定為指派運算子右運算元的運算式會對應到存取子宣告的隱含 value 參數 setFor indexers, when invoking the set accessor, the expression specified as the right operand of the assignment operator corresponds to the implicit value parameter of the set accessor declaration.
• 針對屬性，當叫用存取子時，沒有 get 引數。For properties, when invoking the get accessor there are no arguments. set叫用存取子時，指定為指派運算子右運算元的運算式會對應到存取子宣告的隱含 value 參數 setWhen invoking the set accessor, the expression specified as the right operand of the assignment operator corresponds to the implicit value parameter of the set accessor declaration.
• 如果使用者定義的一元運算子 (包括轉換) ，則單一運算元會對應到運算子宣告的單一參數。For user-defined unary operators (including conversions), the single operand corresponds to the single parameter of the operator declaration.
• 如果是使用者定義的二元運算子，左運算元會對應到第一個參數，右邊的運算元則對應到運算子宣告的第二個參數。For user-defined binary operators, the left operand corresponds to the first parameter, and the right operand corresponds to the second parameter of the operator declaration.

#### 引數清單的執行時間評估Run-time evaluation of argument lists

• 如果是值參數，則會評估引數運算式，並對對應的參數類型執行隱含轉換 (隱含 轉換) 。For a value parameter, the argument expression is evaluated and an implicit conversion (Implicit conversions) to the corresponding parameter type is performed. 產生的值會成為函數成員調用中 value 參數的初始值。The resulting value becomes the initial value of the value parameter in the function member invocation.
• 若為參考或輸出參數，則會評估變數參考，而產生的儲存位置會變成函式成員調用中參數所代表的儲存位置。For a reference or output parameter, the variable reference is evaluated and the resulting storage location becomes the storage location represented by the parameter in the function member invocation. 如果指定為參考或輸出參數的變數參考是 reference_type 的陣列元素，則會執行執行時間檢查，以確保陣列的元素類型與參數的類型相同。If the variable reference given as a reference or output parameter is an array element of a reference_type, a run-time check is performed to ensure that the element type of the array is identical to the type of the parameter. 如果這項檢查失敗， System.ArrayTypeMismatchException 就會擲回。If this check fails, a System.ArrayTypeMismatchException is thrown.

• 以一般形式叫用具有參數陣列的函式成員時，為參數陣列提供的引數必須是可隱含轉換的單一運算式， (隱含轉換) 至參數陣列類型。When a function member with a parameter array is invoked in its normal form, the argument given for the parameter array must be a single expression that is implicitly convertible (Implicit conversions) to the parameter array type. 在此情況下，參數陣列的運作方式與值參數完全相同。In this case, the parameter array acts precisely like a value parameter.
• 當以參數陣列的擴充形式叫用具有參數陣列的函式成員時，調用必須為參數陣列指定零個或更多位置引數，其中每個引數都是可隱含轉換的運算式， (隱含轉換) 為參數陣列的元素類型。When a function member with a parameter array is invoked in its expanded form, the invocation must specify zero or more positional arguments for the parameter array, where each argument is an expression that is implicitly convertible (Implicit conversions) to the element type of the parameter array. 在此情況下，叫用會使用與引數數目對應的長度來建立參數陣列類型的實例，並使用指定的引數值初始化陣列實例的專案，並使用新建立的陣列實例作為實際的引數。In this case, the invocation creates an instance of the parameter array type with a length corresponding to the number of arguments, initializes the elements of the array instance with the given argument values, and uses the newly created array instance as the actual argument.

class Test
{
static void F(int x, int y = -1, int z = -2) {
System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z);
}

static void Main() {
int i = 0;
F(i++, i++, i++);
F(z: i++, x: i++);
}
}


x = 0, y = 1, z = 2
x = 4, y = -1, z = 3


class Test
{
static void F(ref object x) {...}

static void Main() {
object[] a = new object[10];
object[] b = new string[10];
F(ref a[0]);        // Ok
F(ref b[1]);        // ArrayTypeMismatchException
}
}


void F(int x, int y, params object[] args);


F(10, 20);
F(10, 20, 30, 40);
F(10, 20, 1, "hello", 3.0);


F(10, 20, new object[] {});
F(10, 20, new object[] {30, 40});
F(10, 20, new object[] {1, "hello", 3.0});


### 型別推斷Type inference

class Chooser
{
static Random rand = new Random();

public static T Choose<T>(T first, T second) {
return (rand.Next(2) == 0)? first: second;
}
}


int i = Chooser.Choose(5, 213);                 // Calls Choose<int>

string s = Chooser.Choose("foo", "bar");        // Calls Choose<string>


Tr M<X1,...,Xn>(T1 x1, ..., Tm xm)


#### 第一個階段The first phase

• 如果 Ei 是匿名函式，則 明確的參數類型推斷 (明確的參數類型推斷 ，) EiTiIf Ei is an anonymous function, an explicit parameter type inference (Explicit parameter type inferences) is made from Ei to Ti
• 否則，如果的類型為， Ei Uxi 為值參數，則會 進行 較低的 系結推斷 U TiOtherwise, if Ei has a type U and xi is a value parameter then a lower-bound inference is made from U to Ti.
• 否則，如果的 Ei 型別 U xiref 或參數， out 則會 進行 確切的推斷 U TiOtherwise, if Ei has a type U and xi is a ref or out parameter then an exact inference is made from U to Ti.
• 否則，就不會對此引數進行任何推斷。Otherwise, no inference is made for this argument.

#### 第二個階段The second phase

• 所有不會相依于 (相依性) 的未 固定類型變數 Xi Xj ， (修正) 。All unfixed type variables Xi which do not depend on (Dependence) any Xj are fixed (Fixing).
• 如果沒有這 類型 別變數存在，則 Xi 會針對下列所有固定類型變數進行 修正If no such type variables exist, all unfixed type variables Xi are fixed for which all of the following hold:
• 至少有一個類型變數 Xj 相依于 XiThere is at least one type variable Xj that depends on Xi
• Xi 具有非空白的範圍集合Xi has a non-empty set of bounds
• 如果沒有這類型別變數存在，但仍有未 固定 的型別變數，則類型推斷會失敗。If no such type variables exist and there are still unfixed type variables, type inference fails.
• 否則，如果沒有其他未 固定 的類型變數存在，則類型推斷會成功。Otherwise, if no further unfixed type variables exist, type inference succeeds.
• 否則，針對所有 Ei 具有對應參數類型的引數，其中輸出類型 Ti (輸出類型) 包含未處理的類型變數 Xj ，但 輸入 類型 (輸入類型) 沒有，則會 進行輸出 型別推斷 (輸出型 Ei Ti 別推斷。Otherwise, for all arguments Ei with corresponding parameter type Ti where the output types (Output types) contain unfixed type variables Xj but the input types (Input types) do not, an output type inference (Output type inferences) is made from Ei to Ti. 接著會重複第二個階段。Then the second phase is repeated.

#### 依賴Dependence

Xj相依于 Xi如果 Xj 直接相依Xi 或， Xi Xk Xk Xj 則取決於。Xj depends on Xi if Xj depends directly on Xi or if Xi depends directly on Xk and Xk depends on Xj. 因此，「相依于」是可轉移的，但不是「直接相依于」的自反項。Thus "depends on" is the transitive but not reflexive closure of "depends directly on".

#### 輸出類型推斷Output type inferences

• 如果 E 是具有推斷傳回型別的匿名函式 (推斷的傳回型別 U) 而且 T 是具有傳回型別的委派型別或運算式樹狀結構型別，則會向進行下限推斷 Tb () 下限推斷 U TbIf E is an anonymous function with inferred return type U (Inferred return type) and T is a delegate type or expression tree type with return type Tb, then a lower-bound inference (Lower-bound inferences) is made from U to Tb.
• 否則，如果 E 是方法群組，且 T 是具有參數類型和傳回類型的委派類型或運算式樹狀結構類型 T1...Tk Tb ，而且具有類型的多載解析會產生具有傳回類型的 E T1...Tk 單一方法 U ，則會 進行 下限推斷 U TbOtherwise, if E is a method group and T is a delegate type or expression tree type with parameter types T1...Tk and return type Tb, and overload resolution of E with the types T1...Tk yields a single method with return type U, then a lower-bound inference is made from U to Tb.
• 否則，如果 E 是具有類型的運算式 U ，則會 進行 較低的 系結推斷 U TOtherwise, if E is an expression with type U, then a lower-bound inference is made from U to T.
• 否則，就不會進行推斷。Otherwise, no inferences are made.

#### 明確的參數類型推斷Explicit parameter type inferences

• 如果 E 是具有參數類型的明確型別匿名函式 U1...Uk ，而且 T 是具有參數類型的委派類型或運算式樹狀結構類型， V1...Vk 則會對每個 Ui 精確推斷 (精確推斷) Ui 對應的進行 ViIf E is an explicitly typed anonymous function with parameter types U1...Uk and T is a delegate type or expression tree type with parameter types V1...Vk then for each Ui an exact inference (Exact inferences) is made from Ui to the corresponding Vi.

#### 確切推斷Exact inferences

• 如果 V 是其中一個未 修復 的，則 Xi U 會新增至的確切界限集合 XiIf V is one of the unfixed Xi then U is added to the set of exact bounds for Xi.

• 否則， V1...Vk U1...Uk 會檢查是否有下列任何一種情況，以決定是否適用：Otherwise, sets V1...Vk and U1...Uk are determined by checking if any of the following cases apply:

• V是陣列類型 V1[...] ，而且 U 是相同次序的陣列類型 U1[...]V is an array type V1[...] and U is an array type U1[...] of the same rank
• V 是型別 V1? ，而且 U 是型別 U1?V is the type V1? and U is the type U1?
• V 是一種結構化型別 C<V1...Vk> ，而且 U 是一種結構化的型別 C<U1...Uk>V is a constructed type C<V1...Vk>and U is a constructed type C<U1...Uk>

如果有任何一種情況，則會 每個案例對對應的進行 精確推斷 Ui ViIf any of these cases apply then an exact inference is made from each Ui to the corresponding Vi.

• 否則不會進行推斷。Otherwise no inferences are made.

#### 下限推斷Lower-bound inferences

• 如果 V 是其中一個未 修復 的，則 Xi U 會新增至的下限集合 XiIf V is one of the unfixed Xi then U is added to the set of lower bounds for Xi.

• 否則，如果 V 是型別， V1? 而且是型別，則 U U1? 會從開始進行較低 U1 V1 的系結推斷。Otherwise, if V is the type V1?and U is the type U1? then a lower bound inference is made from U1 to V1.

• 否則， U1...Uk V1...Vk 會檢查是否有下列任何一種情況，以決定是否適用：Otherwise, sets U1...Uk and V1...Vk are determined by checking if any of the following cases apply:

• V 是陣列型別 V1[...] ，而且 U 是陣列類型 U1[...] (或有效基底型別 U1[...]) 相同次序的型別參數V is an array type V1[...] and U is an array type U1[...] (or a type parameter whose effective base type is U1[...]) of the same rank

• V 是、或的其中一 IEnumerable<V1> ICollection<V1> IList<V1> U 維陣列類型 U1[] (或有效基底類型為的類型參數 U1[]) V is one of IEnumerable<V1>, ICollection<V1> or IList<V1> and U is a one-dimensional array type U1[](or a type parameter whose effective base type is U1[])

• V 是一種結構化的類別、結構、介面或委派型別 C<V1...Vk> ，而且有一個唯一的型別，也就是 C<U1...Uk> U (或者，如果 U 是型別參數，則它的有效基類或其有效介面集的任何成員) 等同 (于直接或間接) ，或是直接或間接 () C<U1...Uk>V is a constructed class, struct, interface or delegate type C<V1...Vk> and there is a unique type C<U1...Uk> such that U (or, if U is a type parameter, its effective base class or any member of its effective interface set) is identical to, inherits from (directly or indirectly), or implements (directly or indirectly) C<U1...Uk>.

(「唯一性」限制表示在案例介面中 C<T> {} class U: C<X>, C<Y> {} ，從推斷時，不會進行任何推斷， U C<T> 因為 U1 可以是 XY 。 ) (The "uniqueness" restriction means that in the case interface C<T> {} class U: C<X>, C<Y> {}, then no inference is made when inferring from U to C<T> because U1 could be X or Y.)

如果有上述任何一種情況，則會將 每個 案例的推斷進行對應，如下所示 Ui ViIf any of these cases apply then an inference is made from each Ui to the corresponding Vi as follows:

• 如果 Ui 不知道是參考型別，則會進行 確切的推斷If Ui is not known to be a reference type then an exact inference is made
• 否則，如果 U 是陣列型別，則會進行 較低 系結的推斷Otherwise, if U is an array type then a lower-bound inference is made
• 否則，如果 V 為，則 C<V1...Vk> 推斷相依于的第 i 個型別參數 COtherwise, if V is C<V1...Vk> then inference depends on the i-th type parameter of C:
• 如果是協變數，則會進行 較低 系結的推斷。If it is covariant then a lower-bound inference is made.
• 如果是逆變的，則會進行 上限的推斷If it is contravariant then an upper-bound inference is made.
• 如果是不變的，則會進行 完全推斷If it is invariant then an exact inference is made.
• 否則，就不會進行推斷。Otherwise, no inferences are made.

#### 上限推斷Upper-bound inferences

• 如果 V 是其中一個未 固定 的，則 Xi U 會新增至的上限集合 XiIf V is one of the unfixed Xi then U is added to the set of upper bounds for Xi.

• 否則， V1...Vk U1...Uk 會檢查是否有下列任何一種情況，以決定是否適用：Otherwise, sets V1...Vk and U1...Uk are determined by checking if any of the following cases apply:

• U是陣列類型 U1[...] ，而且 V 是相同次序的陣列類型 V1[...]U is an array type U1[...] and V is an array type V1[...] of the same rank

• UIEnumerable<Ue>ICollection<Ue> 或以及一 IList<Ue> V 維陣列類型 Ve[]U is one of IEnumerable<Ue>, ICollection<Ue> or IList<Ue> and V is a one-dimensional array type Ve[]

• U 是型別 U1? ，而且 V 是型別 V1?U is the type U1? and V is the type V1?

• U 是結構化類別、結構、介面或委派型別， C<U1...Uk> 而且 V 是與相同的類別、結構、介面或委派型別，繼承自 (直接或間接) ，或是直接或間接) 唯一的型別來執行 (C<V1...Vk>U is constructed class, struct, interface or delegate type C<U1...Uk> and V is a class, struct, interface or delegate type which is identical to, inherits from (directly or indirectly), or implements (directly or indirectly) a unique type C<V1...Vk>

(「唯一性」限制表示如果有 interface C<T>{} class V<Z>: C<X<Z>>, C<Y<Z>>{} ，則在從推斷至時，不會進行任何 C<U1> 推斷 V<Q>(The "uniqueness" restriction means that if we have interface C<T>{} class V<Z>: C<X<Z>>, C<Y<Z>>{}, then no inference is made when inferring from C<U1> to V<Q>. 推斷並非由或組成 U1 X<Q> Y<Q> 。 ) Inferences are not made from U1 to either X<Q> or Y<Q>.)

如果有上述任何一種情況，則會將 每個 案例的推斷進行對應，如下所示 Ui ViIf any of these cases apply then an inference is made from each Ui to the corresponding Vi as follows:

• 如果 Ui 不知道是參考型別，則會進行 確切的推斷If Ui is not known to be a reference type then an exact inference is made
• 否則，如果 V 是陣列型別，則會進行 上限的推斷Otherwise, if V is an array type then an upper-bound inference is made
• 否則，如果 U 為，則 C<U1...Uk> 推斷相依于的第 i 個型別參數 COtherwise, if U is C<U1...Uk> then inference depends on the i-th type parameter of C:
• 如果是協變數，則會進行 上限的推斷If it is covariant then an upper-bound inference is made.
• 如果是逆變的，則會進行 較低的推斷If it is contravariant then a lower-bound inference is made.
• 如果是不變的，則會進行 完全推斷If it is invariant then an exact inference is made.
• 否則，就不會進行推斷。Otherwise, no inferences are made.

#### 修正Fixing

Xi 具有一組界限 的未 固定型別變數如下所示：An unfixed type variable Xi with a set of bounds is fixed as follows:

• 一組 候選 型別會以一組 Uj 界限內的所有類型集合開始 XiThe set of candidate types Uj starts out as the set of all types in the set of bounds for Xi.
• 接著，我們會逐一檢查每個系結，以 Xi U 找出 Xi 並非完全相同的所有型別， Uj U 從候選集合中移除。We then examine each bound for Xi in turn: For each exact bound U of Xi all types Uj which are not identical to U are removed from the candidate set. 針對沒有 U Xi 隱含轉換的所有類型下限， Uj U 會從候選集移除。For each lower bound U of Xi all types Uj to which there is not an implicit conversion from U are removed from the candidate set. 針對 U Xi 所有沒有隱含轉換之類型的上限， Uj U 都會從候選集移除。For each upper bound U of Xi all types Uj from which there is not an implicit conversion to U are removed from the candidate set.
• 如果其餘的候選型別之間 Uj 有唯一的型別，則會 V 隱含地轉換為所有其他候選型別，然後 Xi 才會修正為 VIf among the remaining candidate types Uj there is a unique type V from which there is an implicit conversion to all the other candidate types, then Xi is fixed to V.
• 否則，型別推斷會失敗。Otherwise, type inference fails.

#### 推斷的傳回型別Inferred return type

• 如果的主體 F 是具有類型的 運算式 ，則推斷的結果型別 F 是該運算式的型別。If the body of F is an expression that has a type, then the inferred result type of F is the type of that expression.
• 如果的主體 F區塊 ，且區塊語句中的一組運算式 return 具有最佳的一般類型 T () 中 尋找一組運算式的最佳一般類型 ，則的推斷結果型別 FTIf the body of F is a block and the set of expressions in the block's return statements has a best common type T (Finding the best common type of a set of expressions), then the inferred result type of F is T.
• 否則，就無法推斷結果型別 FOtherwise, a result type cannot be inferred for F.

• 如果 F 是非同步，而且的主體 F 是分類為 Nothing (運算式分類) 的運算式，或是沒有 return 語句有運算式的語句區塊，則推斷的傳回型別為 System.Threading.Tasks.TaskIf F is async and the body of F is either an expression classified as nothing (Expression classifications), or a statement block where no return statements have expressions, the inferred return type is System.Threading.Tasks.Task
• 如果 F 是非同步，而且具有推斷的結果型別 T ，則推斷的傳回型別為 System.Threading.Tasks.Task<T>If F is async and has an inferred result type T, the inferred return type is System.Threading.Tasks.Task<T>.
• 如果是非非同步， F 而且具有推斷的結果型別 T ，則推斷的傳回型別為 TIf F is non-async and has an inferred result type T, the inferred return type is T.
• 否則，就無法推斷傳回型別 FOtherwise a return type cannot be inferred for F.

namespace System.Linq
{
public static class Enumerable
{
public static IEnumerable<TResult> Select<TSource,TResult>(
this IEnumerable<TSource> source,
Func<TSource,TResult> selector)
{
foreach (TSource element in source) yield return selector(element);
}
}
}


List<Customer> customers = GetCustomerList();
IEnumerable<string> names = customers.Select(c => c.Name);


IEnumerable<string> names = Enumerable.Select(customers, c => c.Name);


Sequence.Select<Customer,string>(customers, (Customer c) => c.Name)


static Z F<X,Y,Z>(X value, Func<X,Y> f1, Func<Y,Z> f2) {
return f2(f1(value));
}


double seconds = F("1:15:30", s => TimeSpan.Parse(s), t => t.TotalSeconds);


#### 方法群組轉換的型別推斷Type inference for conversion of method groups

Tr M<X1...Xn>(T1 x1 ... Tm xm)


M<S1...Sn>


#### 尋找一組運算式的最佳一般類型Finding the best common type of a set of expressions

Tr M<X>(X x1 ... X xm)


with Ei 做為引數。with the Ei as arguments.

• 假設有一組適用的候選函式成員，就會找到該集合中的最佳函數成員。Given the set of applicable candidate function members, the best function member in that set is located. 如果集合中只有一個函式成員，則該函數成員是最佳的函式成員。If the set contains only one function member, then that function member is the best function member. 否則，最好的函式成員就是一個函數成員，比起指定引數清單的所有其他函式成員更好，前提是每個函式成員都是使用 更好的函式成員中的規則來與所有其他函式成員進行比較。Otherwise, the best function member is the one function member that is better than all other function members with respect to the given argument list, provided that each function member is compared to all other function members using the rules in Better function member. 如果沒有正好一個比所有其他函式成員更好的函式成員，則函數成員調用會不明確，而且會發生系結階段錯誤。If there is not exactly one function member that is better than all other function members, then the function member invocation is ambiguous and a binding-time error occurs.

#### 適用的函數成員Applicable function member

• 中的每個引數 A 會對應至函式成員宣告中的參數（如 對應的參數中所述），而且沒有任何引數對應的任何參數都是選擇性參數。Each argument in A corresponds to a parameter in the function member declaration as described in Corresponding parameters, and any parameter to which no argument corresponds is an optional parameter.
• 針對中的每個引數 A ，引數的參數傳遞模式 (例如、值、 refout) 等同于對應參數的參數傳遞模式，以及For each argument in A, the parameter passing mode of the argument (i.e., value, ref, or out) is identical to the parameter passing mode of the corresponding parameter, and
• 如果是值參數或參數陣列， (隱含 轉換) 存在於對應參數類型的引數中，或for a value parameter or a parameter array, an implicit conversion (Implicit conversions) exists from the argument to the type of the corresponding parameter, or
• 針對 refout 參數，引數的類型與對應參數的類型相同。for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter. 畢竟， refout 參數是傳遞引數的別名。After all, a ref or out parameter is an alias for the argument passed.

• 展開的表單的建立方式，是將函數成員宣告中的參數陣列取代為參數陣列元素類型的零或多個值參數，讓引數清單中的引數數目 A 符合參數的總數目。The expanded form is constructed by replacing the parameter array in the function member declaration with zero or more value parameters of the element type of the parameter array such that the number of arguments in the argument list A matches the total number of parameters. 如果 A 引數的引數數目少於函數成員宣告中的固定參數數目，則無法建立函式成員的擴充形式，因此不適用。If A has fewer arguments than the number of fixed parameters in the function member declaration, the expanded form of the function member cannot be constructed and is thus not applicable.
• 否則，如果對 A 引數的參數傳遞模式中的每個引數，都與對應參數的參數傳遞模式相同，則會適用展開的表單，而且Otherwise, the expanded form is applicable if for each argument in A the parameter passing mode of the argument is identical to the parameter passing mode of the corresponding parameter, and
• 若為固定值參數或展開所建立的值參數，隱含轉換 (隱含 轉換) 存在於引數的類型與對應參數的類型，或for a fixed value parameter or a value parameter created by the expansion, an implicit conversion (Implicit conversions) exists from the type of the argument to the type of the corresponding parameter, or
• 針對 refout 參數，引數的類型與對應參數的類型相同。for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter.

#### 更好的函式成員Better function member

• 如果函數成員僅適用于展開的表單，則會使用展開的表單。The expanded form is used if the function member was applicable only in the expanded form.
• 未對應引數的選擇性參數會從參數清單中移除Optional parameters with no corresponding arguments are removed from the parameter list
• 這些參數會重新排序，使其出現在引數清單中與對應引數相同的位置。The parameters are reordered so that they occur at the same position as the corresponding argument in the argument list.

• 針對每個引數，從到到的隱含轉換 Ex Qx 不優於從轉換成的隱含轉換 Ex Px ，以及for each argument, the implicit conversion from Ex to Qx is not better than the implicit conversion from Ex to Px, and
• 若至少有一個引數，從轉換 ExPx 優於從轉換為 Ex Qxfor at least one argument, the conversion from Ex to Px is better than the conversion from Ex to Qx.

• 如果是非 Mp 泛型方法且 Mq 為泛型方法，則 Mp 比更好 MqIf Mp is a non-generic method and Mq is a generic method, then Mp is better than Mq.
• 否則，如果 Mp 適用于其一般形式且 Mq 具有陣列， params 且僅適用于其展開的表單，則 Mp 比更好 MqOtherwise, if Mp is applicable in its normal form and Mq has a params array and is applicable only in its expanded form, then Mp is better than Mq.
• 否則，如果 Mp 的宣告參數多於 Mq ，則 Mp 比更好 MqOtherwise, if Mp has more declared parameters than Mq, then Mp is better than Mq. 如果這兩個方法都具有 params 陣列，且僅適用于其展開的表單，就會發生這種情況。This can occur if both methods have params arrays and are applicable only in their expanded forms.
• 否則，如果的所有參數 Mp 都有對應的引數，而預設引數必須在中至少替代一個選擇性參數，則 Mq Mp 比更好 MqOtherwise if all parameters of Mp have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in Mq then Mp is better than Mq.
• 否則，如果 Mp 有比更多的特定參數類型 Mq ，則 Mp 比更好 MqOtherwise, if Mp has more specific parameter types than Mq, then Mp is better than Mq. 讓和表示和的未具現化 {R1, R2, ..., Rn} {S1, S2, ..., Sn} 和未展開參數類型 Mp MqLet {R1, R2, ..., Rn} and {S1, S2, ..., Sn} represent the uninstantiated and unexpanded parameter types of Mp and Mq. Mp的參數類型比起的更為明確， Mq 如果每個參數的 Rx 特定比更不明確， Sx 而且至少要有一個參數， Rx 則更明確 Sx 地表示：Mp's parameter types are more specific than Mq's if, for each parameter, Rx is not less specific than Sx, and, for at least one parameter, Rx is more specific than Sx:
• 類型參數比非類型參數更不特定。A type parameter is less specific than a non-type parameter.
• 以遞迴方式來說，如果至少有一個型別引數是更特定的類型引數，而且沒有任何類型引數比另一個類型引數更明確，則結構化型別會比另一個具有相同類型) 引數的型別引數 (更明確。Recursively, a constructed type is more specific than another constructed type (with the same number of type arguments) if at least one type argument is more specific and no type argument is less specific than the corresponding type argument in the other.
• 陣列類型比其他陣列類型更明確 (具有相同維度數目的陣列) 如果第一個的元素類型比第二個專案類型更明確。An array type is more specific than another array type (with the same number of dimensions) if the element type of the first is more specific than the element type of the second.
• 否則，如果其中一個成員是非提起運算子，另一個成員是一個帶向的運算子，則未提升的運算子比較好。Otherwise if one member is a non-lifted operator and the other is a lifted operator, the non-lifted one is better.
• 否則，這兩個函數成員都不是比較好的做法。Otherwise, neither function member is better.

#### 完全相符的運算式Exactly matching Expression

• E 有型別 S ，而身分識別轉換存在 STE has a type S, and an identity conversion exists from S to T
• E 是匿名函式， T 它可以是委派型別，也可以是 D 運算式樹狀架構型別， Expression<D> 以及下列其中一個保存：E is an anonymous function, T is either a delegate type D or an expression tree type Expression<D> and one of the following holds:
• X E 在 (推斷的傳回型別) 的參數清單內容中，有一個推斷的傳回型別存在 D ，而且會從傳回型別轉換 XDAn inferred return type X exists for E in the context of the parameter list of D (Inferred return type), and an identity conversion exists from X to the return type of D
• 可能 E 是非非同步，且 D 具有傳回型別 YE 非同步且 D 具有傳回型別 Task<Y> ，而且有下列其中一項保留：Either E is non-async and D has a return type Y or E is async and D has a return type Task<Y>, and one of the following holds:
• 的主體 E 是完全符合的運算式 YThe body of E is an expression that exactly matches Y
• 的主體 E 是語句區塊，其中每個 return 語句會傳回完全相符的運算式 YThe body of E is a statement block where every return statement returns an expression that exactly matches Y

#### 更好的轉換目標Better conversion target

• 從隱含轉換 T1T2 existsAn implicit conversion from T1 to T2 exists
• T1 是委派類型 D1 或運算式樹狀架構類型 Expression<D1>T2 是委派類型 D2 或運算式樹狀結構類型 Expression<D2>D1 具有傳回類型 S1 和下列其中一個保留：T1 is either a delegate type D1 or an expression tree type Expression<D1>, T2 is either a delegate type D2 or an expression tree type Expression<D2>, D1 has a return type S1 and one of the following holds:
• D2 傳回 voidD2 is void returning
• D2 具有傳回型別 S2 ，而且 S1 比起的轉換目標更好 S2D2 has a return type S2, and S1 is a better conversion target than S2
• T1Task<S1>T2Task<S2> ，而且 S1 比起的轉換目標更好 S2T1 is Task<S1>, T2 is Task<S2>, and S1 is a better conversion target than S2
• T1S1 或， S1? 其中 S1 是帶正負號的整數類資料類型，而 T2S2S2? S2 不帶正負號的整數類型。T1 is S1 or S1? where S1 is a signed integral type, and T2 is S2 or S2? where S2 is an unsigned integral type. 具體來說：Specifically:
• S1sbyte S2 ，且為 byteushortuintulongS1 is sbyte and S2 is byte, ushort, uint, or ulong
• S1short S2 ，且為 ushortuint 或。 ulongS1 is short and S2 is ushort, uint, or ulong
• S1int S2 ，且為 uint 、或。 ulongS1 is int and S2 is uint, or ulong
• S1long ，且 S2ulongS1 is long and S2 is ulong

interface I1<T> {...}

interface I2<T> {...}

class G1<U>
{
int F1(U u);                  // Overload resolution for G<int>.F1
int F1(int i);                // will pick non-generic

void F2(I1<U> a);             // Valid overload
void F2(I2<U> a);
}

class G2<U,V>
{
void F3(U u, V v);            // Valid, but overload resolution for
void F3(V v, U u);            // G2<int,int>.F3 will fail

void F4(U u, I1<V> v);        // Valid, but overload resolution for
void F4(I1<V> v, U u);        // G2<I1<int>,int>.F4 will fail

void F5(U u1, I1<V> v2);      // Valid overload
void F5(V v1, U u2);

void F6(ref U u);             // valid overload
void F6(out V v);
}


### 動態多載解析的編譯時間檢查Compile-time checking of dynamic overload resolution

• 使用動態引數的靜態方法呼叫Static method calls with dynamic arguments
• 接收者不是動態運算式的實例方法呼叫Instance method calls where the receiver is not a dynamic expression
• 接收器不是動態運算式的索引子呼叫Indexer calls where the receiver is not a dynamic expression
• 使用動態引數的函式呼叫Constructor calls with dynamic arguments

• 部分類型推斷：不直接或間接相依于型別引數的任何類型引數， dynamic 都會使用 型別推斷的規則來推斷。Partial type inference: Any type argument that does not depend directly or indirectly on an argument of type dynamic is inferred using the rules of Type inference. 其餘的類型引數未知。The remaining type arguments are unknown.
• 部分適用性檢查：根據適用的函式 成員檢查適用性，但忽略類型未知的參數。Partial applicability check: Applicability is checked according to Applicable function member, but ignoring parameters whose types are unknown.
• 如果沒有候選項通過這項測試，就會發生編譯時期錯誤。If no candidate passes this test, a compile-time error occurs.

### 函數成員調用Function member invocation

• 靜態函數成員。Static function members. 這些是實例的函式、靜態方法、靜態屬性存取子，以及使用者定義的運算子。These are instance constructors, static methods, static property accessors, and user-defined operators. 靜態函數成員一律為非虛擬。Static function members are always non-virtual.
• 實例函數成員。Instance function members. 這些是實例方法、實例屬性存取子和索引子存取子。These are instance methods, instance property accessors, and indexer accessors. 實例函數成員為非虛擬或虛擬的，而且一律會在特定的實例上叫用。Instance function members are either non-virtual or virtual, and are always invoked on a particular instance. 實例運算式會計算實例，而且它會在函式成員內變成可存取， this (此存取) 。The instance is computed by an instance expression, and it becomes accessible within the function member as this (This access).

• 如果 M 是靜態函數成員：If M is a static function member:

• 引數清單中會評估 引數清單中所述的引數清單。The argument list is evaluated as described in Argument lists.
• 叫用 MM is invoked.
• 如果 M 是在 value_type 中宣告的實例函數成員：If M is an instance function member declared in a value_type:

• E 會進行評估。E is evaluated. 如果此評估造成例外狀況，則不會執行任何進一步的步驟。If this evaluation causes an exception, then no further steps are executed.
• 如果未 E 分類為變數，則會建立型別的暫存區域變數， E 並將的值指派給 E 該變數。If E is not classified as a variable, then a temporary local variable of E's type is created and the value of E is assigned to that variable. E 然後重新分類為該暫存區域變數的參考。E is then reclassified as a reference to that temporary local variable. 暫時變數可以像內部存取 this M ，但無法以任何其他方式存取。The temporary variable is accessible as this within M, but not in any other way. 因此，只有在 E 是真正的變數時，呼叫端才能觀察到所進行的變更 M thisThus, only when E is a true variable is it possible for the caller to observe the changes that M makes to this.
• 引數清單中會評估 引數清單中所述的引數清單。The argument list is evaluated as described in Argument lists.
• 叫用 MM is invoked. 所參考的變數 E 會成為所參考的 this 變數。The variable referenced by E becomes the variable referenced by this.
• 如果 M 是在 reference_type 中宣告的實例函數成員：If M is an instance function member declared in a reference_type:

• E 會進行評估。E is evaluated. 如果此評估造成例外狀況，則不會執行任何進一步的步驟。If this evaluation causes an exception, then no further steps are executed.
• 引數清單中會評估 引數清單中所述的引數清單。The argument list is evaluated as described in Argument lists.
• 如果的型別 Evalue_type，則會執行) 的裝箱轉換 (將轉換轉換 E 成型別 object ，而且 E 會被視為 object 在下列步驟中的型別。If the type of E is a value_type, a boxing conversion (Boxing conversions) is performed to convert E to type object, and E is considered to be of type object in the following steps. 在此情況下， M 只能是的成員 System.ObjectIn this case, M could only be a member of System.Object.
• 的值 E 會被檢查為有效。The value of E is checked to be valid. 如果的值 Enull ，則會擲回， System.NullReferenceException 且不會執行任何進一步的步驟。If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed.
• 將會決定要叫用的函式成員實作為：The function member implementation to invoke is determined:
• 如果的系結時間型別是介面，則叫用的函 E 式成員是由所 M 參考之實例的執行時間型別所提供的實作為 EIf the binding-time type of E is an interface, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. 這個函式成員是藉由將介面對應規則套用 (介面) 對應 來決定，以判斷由所 M 參考之實例的執行時間型別所提供的實作為 EThis function member is determined by applying the interface mapping rules (Interface mapping) to determine the implementation of M provided by the run-time type of the instance referenced by E.
• 否則，如果是虛擬函式成員，則叫用的函 M 式成員是 M 由所參考之實例的執行時間型別所提供的實作為 EOtherwise, if M is a virtual function member, the function member to invoke is the implementation of M provided by the run-time type of the instance referenced by E. 這個函式成員是藉由套用規則來決定最 (的 虛擬方法) 的虛擬方法 M ，而這是與所參考之實例的執行時間型別有關 EThis function member is determined by applying the rules for determining the most derived implementation (Virtual methods) of M with respect to the run-time type of the instance referenced by E.
• 否則，是非 M 虛擬函式成員，而叫用的函式成員本身就是 MOtherwise, M is a non-virtual function member, and the function member to invoke is M itself.
• 叫用上述步驟中所決定的函式成員執行。The function member implementation determined in the step above is invoked. 所參考的物件 E 會成為所參考的 this 物件。The object referenced by E becomes the object referenced by this.

#### 對盒裝實例的調用Invocations on boxed instances

• 當函數成員是 override 繼承自型別的方法時 object ，會透過型別的實例運算式叫用 objectWhen the function member is an override of a method inherited from type object and is invoked through an instance expression of type object.
• 當函式成員是介面函式成員的執行時，會透過 interface_type 的實例運算式叫用。When the function member is an implementation of an interface function member and is invoked through an instance expression of an interface_type.
• 當函數成員透過委派叫用時。When the function member is invoked through a delegate.

## 主要運算式Primary expressions

primary_expression
: primary_no_array_creation_expression
| array_creation_expression
;

primary_no_array_creation_expression
: literal
| interpolated_string_expression
| simple_name
| parenthesized_expression
| member_access
| invocation_expression
| element_access
| this_access
| base_access
| post_increment_expression
| post_decrement_expression
| object_creation_expression
| delegate_creation_expression
| anonymous_object_creation_expression
| typeof_expression
| checked_expression
| unchecked_expression
| default_value_expression
| nameof_expression
| anonymous_method_expression
| primary_no_array_creation_expression_unsafe
;


object o = new int[3][1];


object o = (new int[3])[1];


### 常值Literals

Primary_expression ，其中包含 值 (值) 分類為值。A primary_expression that consists of a literal (Literals) is classified as a value.

### 插入字串Interpolated strings

Interpolated_string_expression 是由 $ 後面接著一般或逐字字串常值的正負號所組成，其中的洞以 { 和分隔，以 } 括住運算式和格式化規格。An interpolated_string_expression consists of a $ sign followed by a regular or verbatim string literal, wherein holes, delimited by { and }, enclose expressions and formatting specifications. 插入字串運算式是已細分為個別標記的 interpolated_string_literal 結果，如插入 字串常值中所述。An interpolated string expression is the result of an interpolated_string_literal that has been broken up into individual tokens, as described in Interpolated string literals.

interpolated_string_expression
: '$' interpolated_regular_string | '$' interpolated_verbatim_string
;

interpolated_regular_string
: interpolated_regular_string_whole
| interpolated_regular_string_start interpolated_regular_string_body interpolated_regular_string_end
;

interpolated_regular_string_body
: interpolation (interpolated_regular_string_mid interpolation)*
;

interpolation
: expression
| expression ',' constant_expression
;

interpolated_verbatim_string
: interpolated_verbatim_string_whole
| interpolated_verbatim_string_start interpolated_verbatim_string_body interpolated_verbatim_string_end
;

interpolated_verbatim_string_body
: interpolation (interpolated_verbatim_string_mid interpolation)+
;


Interpolated_string_expression 分類為值。An interpolated_string_expression is classified as a value. 如果它立即轉換成 System.IFormattableSystem.FormattableString 使用隱含的插入字串轉換 (隱含 插入字串轉換) ，則插入字串運算式具有該類型。If it is immediately converted to System.IFormattable or System.FormattableString with an implicit interpolated string conversion (Implicit interpolated string conversions), the interpolated string expression has that type. 否則，它會有型別 stringOtherwise, it has the type string.

• 如果 interpolated_regular_string_wholeinterpolated_verbatim_string_whole 遵循 $ 正負號，則格式字串常值就是該 token。If an interpolated_regular_string_whole or an interpolated_verbatim_string_whole follows the $ sign, then the format string literal is that token.
• 否則，格式字串常值包含：Otherwise, the format string literal consists of:
• 第一個 interpolated_regular_string_startinterpolated_verbatim_string_startFirst the interpolated_regular_string_start or interpolated_verbatim_string_start
• 然後，針對每個數位 I 0 N-1Then for each number I from 0 to N-1:
• 的十進位標記法 IThe decimal representation of I
• 然後，如果對應的 插補constant_expression，則 , (逗點) ，後面接著 constant_expression 值的十進位標記法。Then, if the corresponding interpolation has a constant_expression, a , (comma) followed by the decimal representation of the value of the constant_expression
• 然後， interpolated_regular_string_midinterpolated_regular_string_endinterpolated_verbatim_string_mid 或緊接在對應的插補之後的 interpolated_verbatim_string_endThen the interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_mid or interpolated_verbatim_string_end immediately following the corresponding interpolation.

TODO：範例。TODO: examples.

### 簡單名稱Simple names

Simple_name 包含識別碼，並選擇性地接著類型引數清單：A simple_name consists of an identifier, optionally followed by a type argument list:

simple_name
: identifier type_argument_list?
;


Simple_name 是表單 I 或表單的格式 I<A1,...,Ak> ，其中 I 是單一識別碼，而且 <A1,...,Ak> 是選擇性的 type_argument_listA simple_name is either of the form I or of the form I<A1,...,Ak>, where I is a single identifier and <A1,...,Ak> is an optional type_argument_list. 未指定任何 type_argument_list 時，請考慮為 K 零。When no type_argument_list is specified, consider K to be zero. Simple_name 的評估和分類方式如下：The simple_name is evaluated and classified as follows:

• 如果 K 為零，且 simple_name 出現在 區塊 中，而且 區塊 的 (或封閉 區塊 的) 區域變數宣告空間 (宣告) 包含 區域變數、參數或具有名稱的常數  I ，則 simple_name 會參考該區域變數、參數或常數，並分類為變數或值。If K is zero and the simple_name appears within a block and if the block's (or an enclosing block's) local variable declaration space (Declarations) contains a local variable, parameter or constant with name I, then the simple_name refers to that local variable, parameter or constant and is classified as a variable or value.

• 如果 K 為零，且 simple_name 出現在泛型方法宣告的主體中，且該宣告包含具有名稱的類型參數  I ，則 simple_name 會參考該類型參數。If K is zero and the simple_name appears within the body of a generic method declaration and if that declaration includes a type parameter with name I, then the simple_name refers to that type parameter.

• 否則，針對每個實例類型  T (實例類型) ，從立即封入類型宣告的實例類型開始，然後繼續執行每個封入類別或結構宣告的實例類型 (如果有任何) ：Otherwise, for each instance type T (The instance type), starting with the instance type of the immediately enclosing type declaration and continuing with the instance type of each enclosing class or struct declaration (if any):

• 如果 K 為零，且的宣告 T 包含具有名稱的型別參數  I ，則 simple_name 會參考該型別參數。If K is zero and the declaration of T includes a type parameter with name I, then the simple_name refers to that type parameter.
• 否則，如果成員查閱 (成員查閱) 的 I in T 具有類型引數，則會 K   產生相符的結果：Otherwise, if a member lookup (Member lookup) of I in T with K type arguments produces a match:
• 如果 T 是直接封入類別或結構類型的實例類型，而且查閱識別出一或多個方法，則結果為具有相關聯之實例運算式的方法群組 thisIf T is the instance type of the immediately enclosing class or struct type and the lookup identifies one or more methods, the result is a method group with an associated instance expression of this. 如果指定了類型引數清單，則會使用它來呼叫泛型方法， (方法調用) 。If a type argument list was specified, it is used in calling a generic method (Method invocations).
• 否則，如果 T 是直接封入類別或結構類型的實例類型，如果查閱識別實例成員，且參考發生在實例函式的主體、實例方法或實例存取子內，則結果與表單的成員存取 (成員存取) 相同 this.IOtherwise, if T is the instance type of the immediately enclosing class or struct type, if the lookup identifies an instance member, and if the reference occurs within the body of an instance constructor, an instance method, or an instance accessor, the result is the same as a member access (Member access) of the form this.I. 只有當為零時，才會發生這種情況 KThis can only happen when K is zero.
• 否則，結果會與表單或的成員存取 (成員存取) 相同 T.I T.I<A1,...,Ak>Otherwise, the result is the same as a member access (Member access) of the form T.I or T.I<A1,...,Ak>. 在此情況下，它是系結時期錯誤， simple_name 參考實例成員。In this case, it is a binding-time error for the simple_name to refer to an instance member.
• 否則，針對每個命名空間  N ，從 simple_name 發生所在的命名空間開始，繼續每個封入命名空間 (如果有任何) ，並以全域命名空間結束，則會評估下列步驟，直到實體找到為止：Otherwise, for each namespace N, starting with the namespace in which the simple_name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:

• 如果 K 是零，且 I 是命名空間的名稱  N ，則：If K is zero and I is the name of a namespace in N, then:
• 如果發生 simple_name 的位置是由命名空間宣告所括住， N 且命名空間宣告包含 extern_alias_directiveusing_alias_directive ，將名稱  I 與命名空間或類型產生關聯，則 simple_name 不明確，而且會發生編譯時期錯誤。If the location where the simple_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the simple_name is ambiguous and a compile-time error occurs.
• 否則， simple_name 會參考中的命名空間 I NOtherwise, the simple_name refers to the namespace named I in N.
• 否則，如果 N 包含具有 name 和 type 參數的可存取型別  I K   ，則：Otherwise, if N contains an accessible type having name I and K type parameters, then:
• 如果 K 是零，且 simple_name 發生的位置是以命名空間宣告括住， N 且命名空間宣告包含 extern_alias_directiveusing_alias_directive ，將名稱  I 與命名空間或類型產生關聯，則 simple_name 不明確，而且會發生編譯時期錯誤。If K is zero and the location where the simple_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the simple_name is ambiguous and a compile-time error occurs.
• 否則， namespace_or_type_name 會參考以指定的型別引數所構成的型別。Otherwise, the namespace_or_type_name refers to the type constructed with the given type arguments.
• 否則，如果 simple_name 發生的位置是以的命名空間宣告括住  NOtherwise, if the location where the simple_name occurs is enclosed by a namespace declaration for N:
• 如果 K 為零，且命名空間宣告包含 extern_alias_directiveusing_alias_directive ，將名稱  I 與匯入的命名空間或類型產生關聯，則 simple_name 會參考該命名空間或類型。If K is zero and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with an imported namespace or type, then the simple_name refers to that namespace or type.
• 否則，如果由命名空間宣告的 using_namespace_directive s 和 using_static_directive s 所匯入的命名空間和類型宣告，只包含一個可存取的類型或具有名稱和類型參數的非延伸靜態成員  I ，則 K   simple_name 會參考以指定類型引數所建立的該類型或成員。Otherwise, if the namespaces and type declarations imported by the using_namespace_directive s and using_static_directive s of the namespace declaration contain exactly one accessible type or non-extension static member having name I and K type parameters, then the simple_name refers to that type or member constructed with the given type arguments.
• 否則，如果命名空間宣告的 using_namespace_directive s 所匯入的命名空間和型別包含一個以上的可存取型別或非延伸方法靜態成員具有 name  IK   type 參數，則 simple_name 會不明確，而且會發生錯誤。Otherwise, if the namespaces and types imported by the using_namespace_directive s of the namespace declaration contain more than one accessible type or non-extension-method static member having name I and K type parameters, then the simple_name is ambiguous and an error occurs.

請注意，這整個步驟與處理 namespace_or_type_name (命名空間和類型名稱) 的對應步驟完全相同。Note that this entire step is exactly parallel to the corresponding step in the processing of a namespace_or_type_name (Namespace and type names).

• 否則， simple_name 是未定義的，而且會發生編譯時期錯誤。Otherwise, the simple_name is undefined and a compile-time error occurs.

### 括號運算式Parenthesized expressions

Parenthesized_expression 是由以括弧括住的 運算式 所組成。A parenthesized_expression consists of an expression enclosed in parentheses.

parenthesized_expression
: '(' expression ')'
;


Parenthesized_expression 是藉由評估括弧內的 運算式 來評估。A parenthesized_expression is evaluated by evaluating the expression within the parentheses. 如果括弧內的 運算式 表示命名空間或類型，就會發生編譯階段錯誤。If the expression within the parentheses denotes a namespace or type, a compile-time error occurs. 否則， parenthesized_expression 的結果會是所含 運算式 的評估結果。Otherwise, the result of the parenthesized_expression is the result of the evaluation of the contained expression.

### 成員存取Member access

Member_accessprimary_expressionpredefined_typequalified_alias_member 所組成，後面接著 " . " token，後面接著一個 識別碼，可選擇性地接著 type_argument_listA member_access consists of a primary_expression, a predefined_type, or a qualified_alias_member, followed by a "." token, followed by an identifier, optionally followed by a type_argument_list.

member_access
: primary_expression '.' identifier type_argument_list?
| predefined_type '.' identifier type_argument_list?
| qualified_alias_member '.' identifier
;

predefined_type
: 'bool'   | 'byte'  | 'char'  | 'decimal' | 'double' | 'float' | 'int' | 'long'
| 'object' | 'sbyte' | 'short' | 'string'  | 'uint'   | 'ulong' | 'ushort'
;


Qualified_alias_member 生產環境是在 命名空間別名限定詞中定義。The qualified_alias_member production is defined in Namespace alias qualifiers.

Member_access 的格式為表單 E.I 或形式 E.I<A1, ..., Ak> ，其中 E 是主要運算式、是 I 單一識別碼，而且 <A1, ..., Ak> 是選擇性的 type_argument_listA member_access is either of the form E.I or of the form E.I<A1, ..., Ak>, where E is a primary-expression, I is a single identifier and <A1, ..., Ak> is an optional type_argument_list. 未指定任何 type_argument_list 時，請考慮為 K 零。When no type_argument_list is specified, consider K to be zero.

Member_access 的評估和分類方式如下：The member_access is evaluated and classified as follows:

• 如果 K 是零，而且 E 是命名空間且 E 包含具有名稱的嵌套命名空間  I ，則結果為該命名空間。If K is zero and E is a namespace and E contains a nested namespace with name I, then the result is that namespace.
• 否則，如果 E 是命名空間，而且 E 包含具有名稱和類型參數的可存取型別  I ，則 K   結果會是以指定的型別引數所構成的型別。Otherwise, if E is a namespace and E contains an accessible type having name I and K type parameters, then the result is that type constructed with the given type arguments.
• 如果 Epredefined_type 或分類為類型的 primary_expression ，如果不是 E 型別參數，而且如果成員查閱 (的成員查閱) 中的 I 型別 E K   參數產生相符的，則 E.I 會進行評估並分類如下：If E is a predefined_type or a primary_expression classified as a type, if E is not a type parameter, and if a member lookup (Member lookup) of I in E with K type parameters produces a match, then E.I is evaluated and classified as follows:
• 如果 I 識別型別，則結果是以指定的型別引數所構成的型別。If I identifies a type, then the result is that type constructed with the given type arguments.
• 如果 I 識別一或多個方法，則結果為沒有相關聯實例運算式的方法群組。If I identifies one or more methods, then the result is a method group with no associated instance expression. 如果指定了類型引數清單，則會使用它來呼叫泛型方法， (方法調用) 。If a type argument list was specified, it is used in calling a generic method (Method invocations).
• 如果 I 識別 static 屬性，則結果會是沒有相關聯的實例運算式的屬性存取。If I identifies a static property, then the result is a property access with no associated instance expression.
• 如果 I 識別 static 欄位：If I identifies a static field:
• 如果欄位是 readonly ，而參考出現在宣告欄位之類別或結構的靜態函式之外，則結果為值，亦即中靜態欄位的值  I  EIf the field is readonly and the reference occurs outside the static constructor of the class or struct in which the field is declared, then the result is a value, namely the value of the static field I in E.
• 否則，結果會是變數，也就是中的靜態欄位  I  EOtherwise, the result is a variable, namely the static field I in E.
• 如果 I 識別 static 事件：If I identifies a static event:
• 如果參考出現在宣告事件的類別或結構中，且事件已在沒有 event_accessor_declarations (事件) 的情況下宣告，則 E.I 會完全如同 I 靜態欄位一樣處理。If the reference occurs within the class or struct in which the event is declared, and the event was declared without event_accessor_declarations (Events), then E.I is processed exactly as if I were a static field.
• 否則，結果會是沒有相關聯的實例運算式的事件存取。Otherwise, the result is an event access with no associated instance expression.
• 如果 I 識別常數，則結果為值，亦即該常數的值。If I identifies a constant, then the result is a value, namely the value of that constant.
• 如果 I 識別列舉成員，則結果為值，亦即該列舉成員的值。If I identifies an enumeration member, then the result is a value, namely the value of that enumeration member.
• 否則， E.I 就是不正確成員參考，而且會發生編譯時期錯誤。Otherwise, E.I is an invalid member reference, and a compile-time error occurs.
• 如果 E 是屬性存取、索引子存取、變數或值、的型別為的型別，  T 而 with 型別引數的成員查閱 (成員查閱) 會 I T K   產生相符的 E.I 結果，則會進行評估並分類如下：If E is a property access, indexer access, variable, or value, the type of which is T, and a member lookup (Member lookup) of I in T with K type arguments produces a match, then E.I is evaluated and classified as follows:
• 首先，如果 E 是屬性或索引子存取，則會取得 (運算式值) 的屬性或索引子存取值，並將其重新分類 E 為值。First, if E is a property or indexer access, then the value of the property or indexer access is obtained (Values of expressions) and E is reclassified as a value.
• 如果 I 識別一或多個方法，則結果為具有相關聯之實例運算式的方法群組 EIf I identifies one or more methods, then the result is a method group with an associated instance expression of E. 如果指定了類型引數清單，則會使用它來呼叫泛型方法， (方法調用) 。If a type argument list was specified, it is used in calling a generic method (Method invocations).
• 如果 I 識別實例屬性，If I identifies an instance property,
• 如果 Ethis ，則會 I 識別自動執行的屬性 (自動 實) 沒有 setter 的屬性，而且在類別或結構類型的實例的函式中發生參考， T 則結果為變數，也就是由 I 指定之實例中所指定之 auto 屬性的隱藏支援欄位 T thisIf E is this, I identifies an automatically implemented property (Automatically implemented properties) without a setter, and the reference occurs within an instance constructor for a class or struct type T, then the result is a variable, namely the hidden backing field for the auto-property given by I in the instance of T given by this.
• 否則，結果會是具有相關聯的實例運算式的屬性存取  EOtherwise, the result is a property access with an associated instance expression of E.
• 如果 Tclass_type ，並 I 識別該 class_type 的實例欄位：If T is a class_type and I identifies an instance field of that class_type:
• 如果的值 E 為，則會擲回 null System.NullReferenceExceptionIf the value of E is null, then a System.NullReferenceException is thrown.
• 否則，如果欄位是 readonly ，而參考出現在宣告欄位之類別的實例函式之外，則結果為值，也就是所參考之物件中的域值  I  EOtherwise, if the field is readonly and the reference occurs outside an instance constructor of the class in which the field is declared, then the result is a value, namely the value of the field I in the object referenced by E.
• 否則，結果會是變數，也就是所  I 參考之物件中的欄位  EOtherwise, the result is a variable, namely the field I in the object referenced by E.
• 如果 Tstruct_type ，並 I 識別該 struct_type 的實例欄位：If T is a struct_type and I identifies an instance field of that struct_type:
• 如果 E 是值，或如果欄位是， readonly 而參考出現在宣告欄位之結構的實例函式之外，則結果為值，也就是  I 指定之結構實例中的欄位值  EIf E is a value, or if the field is readonly and the reference occurs outside an instance constructor of the struct in which the field is declared, then the result is a value, namely the value of the field I in the struct instance given by E.
• 否則，結果會是變數，也就是  I 指定之結構實例中的欄位  EOtherwise, the result is a variable, namely the field I in the struct instance given by E.
• 如果 I 識別實例事件：If I identifies an instance event:
• 如果參考出現在宣告事件的類別或結構中，且事件未 event_accessor_declarations (事件) 的情況下宣告，而且參考不會在或運算子的左邊進行 += ，則 -= E.I 會如同 I 實例欄位一樣處理該參考。If the reference occurs within the class or struct in which the event is declared, and the event was declared without event_accessor_declarations (Events), and the reference does not occur as the left-hand side of a += or -= operator, then E.I is processed exactly as if I was an instance field.
• 否則，結果會是具有相關聯之實例運算式的事件存取  EOtherwise, the result is an event access with an associated instance expression of E.
• 否則，系統會嘗試將 E.I (擴充方法 調用) 的擴充方法調用進行處理。Otherwise, an attempt is made to process E.I as an extension method invocation (Extension method invocations). 如果失敗， E.I 是不正確成員參考，且發生系結階段錯誤。If this fails, E.I is an invalid member reference, and a binding-time error occurs.

#### 相同的簡單名稱和類型名稱Identical simple names and type names

struct Color
{
public static readonly Color White = new Color(...);
public static readonly Color Black = new Color(...);

public Color Complement() {...}
}

class A
{
public Color Color;                // Field Color of type Color

void F() {
Color = Color.Black;           // References Color.Black static member
Color = Color.Complement();    // Invokes Complement() on Color field
}

static void G() {
Color c = Color.White;         // References Color.White static member
}
}


#### 文法多義性Grammar ambiguities

Simple_name (簡單名稱的生產) 和 Member_access (成員存取) 可能會在運算式的文法中提供明顯的多義性。The productions for simple_name (Simple names) and member_access (Member access) can give rise to ambiguities in the grammar for expressions. 例如，語句：For example, the statement:

F(G<A,B>(7));


(  )  ]  }  :  ;  ,  .  ?  ==  !=  |  ^


F(G<A,B>(7));


F(G < A, B > 7);
F(G < A, B >> 7);


x = F < A > +y;


x = y is C<T> + z;


### 叫用運算式Invocation expressions

invocation_expression
: primary_expression '(' argument_list? ')'
;


• Primary_expression 具有編譯時間類型 dynamicThe primary_expression has compile-time type dynamic.
• 選擇性 argument_list 至少有一個引數具有編譯時間類型 dynamic ，而且 primary_expression 沒有委派類型。At least one argument of the optional argument_list has compile-time type dynamic and the primary_expression does not have a delegate type.

Invocation_expressionprimary_expression 必須是方法群組或 delegate_type 的值。The primary_expression of an invocation_expression must be a method group or a value of a delegate_type. 如果 primary_expression 是方法群組，則 invocation_expression 是方法調用， (方法 調用) 。If the primary_expression is a method group, the invocation_expression is a method invocation (Method invocations). 如果 primary_expressiondelegate_type 的值，則 invocation_expression 為委派調用， (委派調用) 。If the primary_expression is a value of a delegate_type, the invocation_expression is a delegate invocation (Delegate invocations). 如果 primary_expression 不是方法群組，也不是 delegate_type 的值，則會發生系結階段錯誤。If the primary_expression is neither a method group nor a value of a delegate_type, a binding-time error occurs.

• 如果 invocation_expression 叫用傳回的方法或委派 void ，則結果為 nothing。If the invocation_expression invokes a method or delegate that returns void, the result is nothing. 分類為 nothing 的運算式只允許在 statement_expression (運算式語句 的內容中) 或作為 lambda_expression (匿名函式 運算式 的主體) 。An expression that is classified as nothing is permitted only in the context of a statement_expression (Expression statements) or as the body of a lambda_expression (Anonymous function expressions). 否則，就會發生系結階段錯誤。Otherwise a binding-time error occurs.
• 否則，結果會是方法或委派所傳回之類型的值。Otherwise, the result is a value of the type returned by the method or delegate.

#### 方法調用Method invocations

• 會建立方法調用的候選方法集合。The set of candidate methods for the method invocation is constructed. 針對 F 與方法群組相關聯的每個方法 MFor each method F associated with the method group M:
• 如果 F 是非泛型，則在下列情況下 F 為候選：If F is non-generic, F is a candidate when:
• M 沒有類型引數清單，且為M has no type argument list, and
• F 適用于 A (適用的函數成員) 。F is applicable with respect to A (Applicable function member).
• 如果 F 是泛型且沒有 M 類型引數清單， F 則在下列情況下是候選項：If F is generic and M has no type argument list, F is a candidate when:
• 型別推斷 (類型推斷) 成功、推斷呼叫類型引數的清單，以及Type inference (Type inference) succeeds, inferring a list of type arguments for the call, and
• 當推斷的型別引數取代為對應的方法型別參數時，F 的參數清單中的所有結構化型別都會滿足其條件約束， (符合) 的 條件約束 ，而的參數清單 F 適用于 A (適用的函數成員) 。Once the inferred type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (Satisfying constraints), and the parameter list of F is applicable with respect to A (Applicable function member).
• 如果 F 是泛型且 M 包含型別引數清單，則在下列情況下 F 是候選項：If F is generic and M includes a type argument list, F is a candidate when:
• F 具有與類型引數清單中所提供之相同的方法類型參數數目，以及F has the same number of method type parameters as were supplied in the type argument list, and
• 一旦將型別引數替換為對應的方法型別參數，F 的參數清單中的所有結構化型別就會滿足其條件約束， (符合) 的 條件約束 ，而的參數清單 F 適用于 A (適用的函數成員) 。Once the type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list of F satisfy their constraints (Satisfying constraints), and the parameter list of F is applicable with respect to A (Applicable function member).
• 這組候選方法會縮減成隻包含來自最多衍生類型的方法：針對集合中的每個方法 C.F ，其中 C 是宣告方法的類型， F 在基底類型中宣告的所有方法 C 都會從集合中移除。The set of candidate methods is reduced to contain only methods from the most derived types: For each method C.F in the set, where C is the type in which the method F is declared, all methods declared in a base type of C are removed from the set. 此外，如果 C 是以外的類別型別 object ，則會從集合中移除在介面型別中宣告的所有方法。Furthermore, if C is a class type other than object, all methods declared in an interface type are removed from the set. (這個第二個規則只有當方法群組是成員查閱的結果，而該型別參數具有物件以外的有效基類和非空白的有效介面集時，才會有影響。 ) (This latter rule only has affect when the method group was the result of a member lookup on a type parameter having an effective base class other than object and a non-empty effective interface set.)
• 如果產生的候選方法集合是空的，則會放棄下列步驟的進一步處理，而改為嘗試將叫用視為擴充方法調用， (擴充方法 調用) 。If the resulting set of candidate methods is empty, then further processing along the following steps are abandoned, and instead an attempt is made to process the invocation as an extension method invocation (Extension method invocations). 如果失敗，就不會有任何適用的方法存在，而且會發生系結階段錯誤。If this fails, then no applicable methods exist, and a binding-time error occurs.
• 您可以使用多載解析規則的多 載解析規則來識別候選方法集合的最佳方法。The best method of the set of candidate methods is identified using the overload resolution rules of Overload resolution. 如果無法識別單一最佳方法，則方法調用會不明確，而且會發生系結階段錯誤。If a single best method cannot be identified, the method invocation is ambiguous, and a binding-time error occurs. 執行多載解析時，會在將類型引數替換為對應方法類型參數的 (提供或推斷) 之後，考慮泛型方法的參數。When performing overload resolution, the parameters of a generic method are considered after substituting the type arguments (supplied or inferred) for the corresponding method type parameters.
• 執行所選最佳方法的最終驗證：Final validation of the chosen best method is performed:
• 方法會在方法群組的內容中進行驗證：如果最理想的方法是靜態方法，則方法群組必須由 simple_namemember_access 透過型別產生。The method is validated in the context of the method group: If the best method is a static method, the method group must have resulted from a simple_name or a member_access through a type. 如果最佳方法是實例方法，則方法群組必須由 simple_name、透過變數或值 member_access ，或 base_access 所產生。If the best method is an instance method, the method group must have resulted from a simple_name, a member_access through a variable or value, or a base_access. 如果上述兩項需求都不成立，就會發生系結階段錯誤。If neither of these requirements is true, a binding-time error occurs.
• 如果最理想的方法是泛型方法， (提供或) 推斷的型別引數會根據條件約束進行檢查， (滿足泛型方法) 所宣告的 條件約束If the best method is a generic method, the type arguments (supplied or inferred) are checked against the constraints (Satisfying constraints) declared on the generic method. 如果任何類型引數無法滿足類型參數上 (s) 的對應條件約束，就會發生系結階段錯誤。If any type argument does not satisfy the corresponding constraint(s) on the type parameter, a binding-time error occurs.

#### 擴充方法調用Extension method invocations

expr . identifier ( )

expr . identifier ( args )

expr . identifier < typeargs > ( )

expr . identifier < typeargs > ( args )


C . identifier ( expr )

C . identifier ( expr , args )

C . identifier < typeargs > ( expr )

C . identifier < typeargs > ( expr , args )


• Ci 是非泛型、非嵌套類別Ci is a non-generic, non-nested class
• 的名稱 Mj識別碼The name of Mj is identifier
• Mj 適用于將引數套用至引數作為靜態方法時，如上所示Mj is accessible and applicable when applied to the arguments as a static method as shown above
• expr 到的第一個參數型別，都有隱含的識別、參考或裝箱轉換 MjAn implicit identity, reference or boxing conversion exists from expr to the type of the first parameter of Mj.

• 從最接近的封入命名空間宣告開始，繼續每個封入命名空間宣告，並以包含的編譯單位結束，就會進行後續的嘗試，以找出一組候選的擴充方法：Starting with the closest enclosing namespace declaration, continuing with each enclosing namespace declaration, and ending with the containing compilation unit, successive attempts are made to find a candidate set of extension methods:
• 如果指定的命名空間或編譯單位直接包含具有合格延伸方法的非泛型型別宣告 Ci Mj ，則這些擴充方法的集合就是候選集合。If the given namespace or compilation unit directly contains non-generic type declarations Ci with eligible extension methods Mj, then the set of those extension methods is the candidate set.
• 如果 using_static_declarations 匯入的型別 Ci ，以及在指定的命名空間或編譯單位中 using_namespace_directive s 匯入之命名空間中直接宣告的型別包含合格的擴充方法 Mj ，則這些擴充方法的集合就是候選集合。If types Ci imported by using_static_declarations and directly declared in namespaces imported by using_namespace_directive s in the given namespace or compilation unit directly contain eligible extension methods Mj, then the set of those extension methods is the candidate set.
• 如果在任何封入命名空間宣告或編譯單位中都找不到候選集合，則會發生編譯時期錯誤。If no candidate set is found in any enclosing namespace declaration or compilation unit, a compile-time error occurs.
• 否則，多載解析會套用至候選集合，如 (多載 解析) 中所述。Otherwise, overload resolution is applied to the candidate set as described in (Overload resolution). 如果找不到單一最佳方法，就會發生編譯時期錯誤。If no single best method is found, a compile-time error occurs.
• C 這是在其中將最佳方法宣告為擴充方法的型別。C is the type within which the best method is declared as an extension method.

public static class E
{
public static void F(this object obj, int i) { }

public static void F(this object obj, string s) { }
}

class A { }

class B
{
public void F(int i) { }
}

class C
{
public void F(object obj) { }
}

class X
{
static void Test(A a, B b, C c) {
a.F(1);              // E.F(object, int)
a.F("hello");        // E.F(object, string)

b.F(1);              // B.F(int)
b.F("hello");        // E.F(object, string)

c.F(1);              // C.F(object)
c.F("hello");        // C.F(object)
}
}


public static class C
{
public static void F(this int i) { Console.WriteLine("C.F({0})", i); }
public static void G(this int i) { Console.WriteLine("C.G({0})", i); }
public static void H(this int i) { Console.WriteLine("C.H({0})", i); }
}

namespace N1
{
public static class D
{
public static void F(this int i) { Console.WriteLine("D.F({0})", i); }
public static void G(this int i) { Console.WriteLine("D.G({0})", i); }
}
}

namespace N2
{
using N1;

public static class E
{
public static void F(this int i) { Console.WriteLine("E.F({0})", i); }
}

class Test
{
static void Main(string[] args)
{
1.F();
2.G();
3.H();
}
}
}


E.F(1)
D.G(2)
C.H(3)


D.G 優先于 C.G ，且優先 E.FD.FC.FD.G takes precedence over C.G, and E.F takes precedence over both D.F and C.F.

#### 委派調用Delegate invocations

• D 會進行評估。D is evaluated. 如果此評估造成例外狀況，則不會執行任何進一步的步驟。If this evaluation causes an exception, no further steps are executed.
• 的值 D 會被檢查為有效。The value of D is checked to be valid. 如果的值 Dnull ，則會擲回， System.NullReferenceException 且不會執行任何進一步的步驟。If the value of D is null, a System.NullReferenceException is thrown and no further steps are executed.
• 否則， D 就是委派實例的參考。Otherwise, D is a reference to a delegate instance. 函數成員調用 (動態多載解析的編譯時間檢查) 是在委派的調用清單中的每個可呼叫實體上執行。Function member invocations (Compile-time checking of dynamic overload resolution) are performed on each of the callable entities in the invocation list of the delegate. 針對由實例和實例方法所組成的可呼叫實體，調用的實例是包含在可呼叫實體中的實例。For callable entities consisting of an instance and instance method, the instance for the invocation is the instance contained in the callable entity.

### 項目存取Element access

Element_accessprimary_no_array_creation_expression 所組成，後面接著 " [ " token，後面接著 argument_list，後面接著 " ] " token。An element_access consists of a primary_no_array_creation_expression, followed by a "[" token, followed by an argument_list, followed by a "]" token. Argument_list 是由一或多個 引數（以逗號分隔）所組成。The argument_list consists of one or more argument s, separated by commas.

element_access
: primary_no_array_creation_expression '[' expression_list ']'
;


Element_accessargument_list 不能包含 refout 引數。The argument_list of an element_access is not allowed to contain ref or out arguments.

• Primary_no_array_creation_expression 具有編譯時間類型 dynamicThe primary_no_array_creation_expression has compile-time type dynamic.
• Argument_list 至少有一個運算式具有編譯時間類型 dynamic ，而且 primary_no_array_creation_expression 沒有陣列類型。At least one expression of the argument_list has compile-time type dynamic and the primary_no_array_creation_expression does not have an array type.

#### 陣列存取Array access

• P 會進行評估。P is evaluated. 如果此評估造成例外狀況，則不會執行任何進一步的步驟。If this evaluation causes an exception, no further steps are executed.
• Argument_list 的索引運算式會依序從左至右進行評估。The index expressions of the argument_list are evaluated in order, from left to right. 在評估每個索引運算式之後，會執行隱含轉換 (隱含 轉換) 為下列其中一種類型： intuintlongulongFollowing evaluation of each index expression, an implicit conversion (Implicit conversions) to one of the following types is performed: int, uint, long, ulong. 此清單中的第一個類型會選擇隱含轉換存在。The first type in this list for which an implicit conversion exists is chosen. 比方說，如果索引運算式的型別為 short int ，則會執行隱含轉換，因為可能會將隱含轉換成 short intshort from longFor instance, if the index expression is of type short then an implicit conversion to int is performed, since implicit conversions from short to int and from short to long are possible. 如果索引運算式的評估或後續的隱含轉換造成例外狀況，則不會評估進一步的索引運算式，也不會執行任何進一步的步驟。If evaluation of an index expression or the subsequent implicit conversion causes an exception, then no further index expressions are evaluated and no further steps are executed.
• 的值 P 會被檢查為有效。The value of P is checked to be valid. 如果的值 Pnull ，則會擲回， System.NullReferenceException 且不會執行任何進一步的步驟。If the value of P is null, a System.NullReferenceException is thrown and no further steps are executed.
• 會根據所參考陣列實例的每個維度的實際界限，檢查 argument_list 中每個運算式的值 PThe value of each expression in the argument_list is checked against the actual bounds of each dimension of the array instance referenced by P. 如果有一或多個值超出範圍，則會擲回， System.IndexOutOfRangeException 且不會執行任何進一步的步驟。If one or more values are out of range, a System.IndexOutOfRangeException is thrown and no further steps are executed.
• 索引運算式 (s) 所提供的陣列元素位置會計算出來，而且這個位置會成為陣列存取的結果。The location of the array element given by the index expression(s) is computed, and this location becomes the result of the array access.

#### 索引子存取Indexer access

• 由所提供的索引子集 TThe set of indexers provided by T is constructed. 此集合包含在中宣告的所有索引子， T 或的基底類型 T 不是宣告 override ，而且可以在目前的內容中存取 (成員存取) 。The set consists of all indexers declared in T or a base type of T that are not override declarations and are accessible in the current context (Member access).
• 此集合會縮減為適用且不被其他索引子隱藏的索引子。The set is reduced to those indexers that are applicable and not hidden by other indexers. 下列規則會套用至集合中的每個索引子 S.I ，其中是用來宣告 S 索引子的類型 IThe following rules are applied to each indexer S.I in the set, where S is the type in which the indexer I is declared:
• 如果不適 I 用於 A (適用的函數成員) ，則 I 會從集合中移除。If I is not applicable with respect to A (Applicable function member), then I is removed from the set.
• 如果 I 適用于 (適用的函式 A 成員) ，則基底類型中宣告的所有索引子 S 都會從集合中移除。If I is applicable with respect to A (Applicable function member), then all indexers declared in a base type of S are removed from the set.
• 如果 I 適用于 (適用的函式 A 成員) ，而且 S 是以外的類別型別 object ，則會從集合中移除所有在介面中宣告的索引子。If I is applicable with respect to A (Applicable function member) and S is a class type other than object, all indexers declared in an interface are removed from the set.
• 如果產生的候選索引子集合是空的，則不存在任何適用的索引子，而且會發生系結階段錯誤。If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a binding-time error occurs.
• 您可以使用多載解析規則的多 載解析規則來識別候選索引子集的最佳索引子。The best indexer of the set of candidate indexers is identified using the overload resolution rules of Overload resolution. 如果無法識別單一的最佳索引子，索引子存取就不明確，而且會發生系結階段錯誤。If a single best indexer cannot be identified, the indexer access is ambiguous, and a binding-time error occurs.
• Argument_list 的索引運算式會依序從左至右進行評估。The index expressions of the argument_list are evaluated in order, from left to right. 處理索引子存取的結果是分類為索引子存取的運算式。The result of processing the indexer access is an expression classified as an indexer access. 索引子存取運算式會參考上一個步驟中所決定的索引子，而且有相關聯的實例運算式 P 和相關聯的引數清單 AThe indexer access expression references the indexer determined in the step above, and has an associated instance expression of P and an associated argument list of A.

### 這種存取權This access

This_access 包含保留字 thisA this_access consists of the reserved word this.

this_access
: 'this'
;


• this 在類別的實例函式內的 primary_expression 中使用時，它會分類為值。When this is used in a primary_expression within an instance constructor of a class, it is classified as a value. 值的類型是實例類型， (使用發生所在之類別的 實例類型) ，而值則是所要建立之物件的參考。The type of the value is the instance type (The instance type) of the class within which the usage occurs, and the value is a reference to the object being constructed.
• this 用於類別的實例方法或實例存取子內的 primary_expression 時，它會分類為值。When this is used in a primary_expression within an instance method or instance accessor of a class, it is classified as a value. 值的類型是實例類型， (使用發生所在之類別的 實例類型) ，而值則是對其叫用方法或存取子之物件的參考。The type of the value is the instance type (The instance type) of the class within which the usage occurs, and the value is a reference to the object for which the method or accessor was invoked.
• this 在結構的實例函式內的 primary_expression 中使用時，它會分類為變數。When this is used in a primary_expression within an instance constructor of a struct, it is classified as a variable. 變數的類型是實例類型， (使用發生所在之結構的 實例類型) ，而變數代表所要建立的結構。The type of the variable is the instance type (The instance type) of the struct within which the usage occurs, and the variable represents the struct being constructed. this結構的實例函式的變數行為與結構類型的參數完全相同，特別是 out 這表示必須在實例的每個執行路徑中明確地指派變數。The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type—in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor.
• this 在結構的實例方法或實例存取子內的 primary_expression 中使用時，它會分類為變數。When this is used in a primary_expression within an instance method or instance accessor of a struct, it is classified as a variable. 變數的類型是實例類型， (使用發生所在之結構的 實例類型) 。The type of the variable is the instance type (The instance type) of the struct within which the usage occurs.
• 如果方法或存取子不是反覆運算器 (反覆運算 器) ，則 this 變數代表叫用方法或存取子的結構，而且行為與 ref 結構類型的參數完全相同。If the method or accessor is not an iterator (Iterators), the this variable represents the struct for which the method or accessor was invoked, and behaves exactly the same as a ref parameter of the struct type.
• 如果方法或存取子是反覆運算器，則 this 變數代表已叫用方法或存取子之結構的複本，而且行為與結構類型的值參數完全相同。If the method or accessor is an iterator, the this variable represents a copy of the struct for which the method or accessor was invoked, and behaves exactly the same as a value parameter of the struct type.

thisprimary_expression 于上述內容以外的內容中使用，是編譯時期錯誤。Use of this in a primary_expression in a context other than the ones listed above is a compile-time error. 尤其是，無法 this 在靜態方法、靜態屬性存取子或欄位宣告的 variable_initializer 中參考。In particular, it is not possible to refer to this in a static method, a static property accessor, or in a variable_initializer of a field declaration.

### 基底存取Base access

Base_access 包含保留字， base 後面接著 " . " 權杖和識別碼或以方括弧括住的 argument_listA base_access consists of the reserved word base followed by either a "." token and an identifier or an argument_list enclosed in square brackets:

base_access
: 'base' '.' identifier
| 'base' '[' expression_list ']'
;


Base_access 是用來存取基類成員，這些成員在目前的類別或結構中以類似的命名成員隱藏。A base_access is used to access base class members that are hidden by similarly named members in the current class or struct. 只有在實例的函式、實例方法或實例存取子的 區塊 中，才允許 base_accessA base_access is permitted only in the block of an instance constructor, an instance method, or an instance accessor. base.I發生于類別或結構時， I 必須表示該類別或結構的基類成員。When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct. 同樣地， base[E] 在類別中發生時，適用的索引子必須存在於基類中。Likewise, when base[E] occurs in a class, an applicable indexer must exist in the base class.

base_access 參考 (方法、屬性或索引子) 的虛擬函式成員時，會決定在執行時間時要叫用的函式成員 (編譯時間檢查動態 多載解析) 變更。When a base_access references a virtual function member (a method, property, or indexer), the determination of which function member to invoke at run-time (Compile-time checking of dynamic overload resolution) is changed. 所叫用的函式成員是藉由尋找最常衍生的實 (虛擬方法) 的函 B 式 (成員，而不是相對於的執行時間類型 this ，如同在非基底存取) 中一般。The function member that is invoked is determined by finding the most derived implementation (Virtual methods) of the function member with respect to B (instead of with respect to the run-time type of this, as would be usual in a non-base access). 因此，在 override virtual 函數成員的中， base_access 可以用來叫用繼承的函式成員實作為。Thus, within an override of a virtual function member, a base_access can be used to invoke the inherited implementation of the function member. 如果 base_access 所參考的函數成員是抽象的，則會發生系結階段錯誤。If the function member referenced by a base_access is abstract, a binding-time error occurs.

### 後置遞增和遞減運算子Postfix increment and decrement operators

post_increment_expression
: primary_expression '++'
;

post_decrement_expression
: primary_expression '--'
;


• 如果 x 分類為變數：If x is classified as a variable:
• x 會評估以產生變數。x is evaluated to produce the variable.
• 的值 x 會儲存。The value of x is saved.
• 使用已儲存的值 x 做為其引數來叫用選取的運算子。The selected operator is invoked with the saved value of x as its argument.
• 運算子所傳回的值會儲存在評估所指定的位置 xThe value returned by the operator is stored in the location given by the evaluation of x.
• 的儲存值 x 會成為作業的結果。The saved value of x becomes the result of the operation.
• 如果 x 分類為屬性或索引子存取：If x is classified as a property or indexer access:
• 如果不是) ，實例運算式 (x static ，且如果 x 是與相關聯的索引子存取) ，則會評估引數 (清單 x ，且結果會用於後續 getset 存取子調用。The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations.
• 會叫用的 get 存取子 x ，並儲存傳回的值。The get accessor of x is invoked and the returned value is saved.
• 使用已儲存的值 x 做為其引數來叫用選取的運算子。The selected operator is invoked with the saved value of x as its argument.
• set 存取子 x 會以運算子傳回的值做為其引數來叫用 valueThe set accessor of x is invoked with the value returned by the operator as its value argument.
• 的儲存值 x 會成為作業的結果。The saved value of x becomes the result of the operation.

++And -- 運算子也支援前置詞標記法 (首碼遞增和遞減運算子) 。The ++ and -- operators also support prefix notation (Prefix increment and decrement operators). 或的結果通常是在作業 x++ x-- 之前的值 x ，而或的結果 ++x 是作業之後的 --xxTypically, the result of x++ or x-- is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. 在任一種情況下， x 其本身在作業之後都具有相同的值。In either case, x itself has the same value after the operation.

operator ++ operator -- 可以使用後置或前置標記法來叫用或實作為。An operator ++ or operator -- implementation can be invoked using either postfix or prefix notation. 這兩種標記法不能有個別的運算子實現。It is not possible to have separate operator implementations for the two notations.

### new 運算子The new operator

new運算子用來建立類型的新實例。The new operator is used to create new instances of types.

• 物件建立運算式可用來建立類別型別和實數值型別的新實例。Object creation expressions are used to create new instances of class types and value types.
• 陣列建立運算式可用來建立陣列類型的新實例。Array creation expressions are used to create new instances of array types.
• 委派建立運算式是用來建立委派類型的新實例。Delegate creation expressions are used to create new instances of delegate types.

new運算子意指建立型別的實例，但不一定表示動態配置記憶體。The new operator implies creation of an instance of a type, but does not necessarily imply dynamic allocation of memory. 尤其是實值型別的實例不需要額外的記憶體，就是它們所在的變數，而且當 new 用來建立實值型別的實例時，不會發生任何動態配置。In particular, instances of value types require no additional memory beyond the variables in which they reside, and no dynamic allocations occur when new is used to create instances of value types.

#### 物件建立運算式Object creation expressions

Object_creation_expression 用來建立 class_typevalue_type 的新實例。An object_creation_expression is used to create a new instance of a class_type or a value_type.

object_creation_expression
: 'new' type '(' argument_list? ')' object_or_collection_initializer?
| 'new' type object_or_collection_initializer
;

object_or_collection_initializer
: object_initializer
| collection_initializer
;


Object_creation_expression 別必須是 class_typevalue_typetype_parameterThe type of an object_creation_expression must be a class_type, a value_type or a type_parameter. 類型 不能是 abstract class_typeThe type cannot be an abstract class_type.

• 如果 Tvalue_typeA 不存在：If T is a value_type and A is not present:
• Object_creation_expression 是預設的函式呼叫。The object_creation_expression is a default constructor invocation. Object_creation_expression 的結果是類型的值，也就是在 T T system.object 類型中定義的預設值。The result of the object_creation_expression is a value of type T, namely the default value for T as defined in The System.ValueType type.
• 否則，如果 Ttype_parameter 且不 A 存在：Otherwise, if T is a type_parameter and A is not present:
• 如果未指定任何實值型別條件約束或函式條件約束 (類型參數條件 約束) T ，就會發生系結階段錯誤。If no value type constraint or constructor constraint (Type parameter constraints) has been specified for T, a binding-time error occurs.
• Object_creation_expression 的結果是型別參數已系結之執行時間類型的值，也就是叫用該型別的預設函式的結果。The result of the object_creation_expression is a value of the run-time type that the type parameter has been bound to, namely the result of invoking the default constructor of that type. 執行時間類型可以是參考型別或實值型別。The run-time type may be a reference type or a value type.
• 否則，如果 Tclass_typestruct_typeOtherwise, if T is a class_type or a struct_type:
• 如果 Tabstract class_type，就會發生編譯時期錯誤。If T is an abstract class_type, a compile-time error occurs.
• 要叫用的實例函式是使用多載解析規則的多載解析規則來決定。The instance constructor to invoke is determined using the overload resolution rules of Overload resolution. 這組候選實例的函式是由中宣告的所有可存取的實例函式所組成， T 這些都適用于 A (適用的函數成員) 。The set of candidate instance constructors consists of all accessible instance constructors declared in T which are applicable with respect to A (Applicable function member). 如果候選實例的函式集合是空的，或無法識別單一最佳實例的函式，則會發生系結階段錯誤。If the set of candidate instance constructors is empty, or if a single best instance constructor cannot be identified, a binding-time error occurs.
• Object_creation_expression 的結果是類型的值，也就是叫用 T 上述步驟中所決定的實例函式所產生的值。The result of the object_creation_expression is a value of type T, namely the value produced by invoking the instance constructor determined in the step above.
• 否則， object_creation_expression 無效，而且會發生系結階段錯誤。Otherwise, the object_creation_expression is invalid, and a binding-time error occurs.

• 如果 Tclass_typeIf T is a class_type:
• 配置給類別的新實例 TA new instance of class T is allocated. 如果沒有足夠的記憶體可配置新的實例，則會擲回， System.OutOfMemoryException 且不會執行任何進一步的步驟。If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
• 新實例的所有欄位都會初始化為預設值 (預設值) 。All fields of the new instance are initialized to their default values (Default values).
• 根據函數成員調用的規則叫用實例的函式， (動態多載解析) 的編譯時期檢查The instance constructor is invoked according to the rules of function member invocation (Compile-time checking of dynamic overload resolution). 新配置之實例的參考會自動傳遞給實例的函式，而且可以在該函式內以形式存取實例 thisA reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this.
• 如果 Tstruct_typeIf T is a struct_type:
• 型別的實例 T 是藉由配置暫存區域變數所建立。An instance of type T is created by allocating a temporary local variable. 由於 struct_type 的實例函式必須將值明確指派給要建立之實例的每個欄位，因此不需要初始化暫存變數。Since an instance constructor of a struct_type is required to definitely assign a value to each field of the instance being created, no initialization of the temporary variable is necessary.
• 根據函數成員調用的規則叫用實例的函式， (動態多載解析) 的編譯時期檢查The instance constructor is invoked according to the rules of function member invocation (Compile-time checking of dynamic overload resolution). 新配置之實例的參考會自動傳遞給實例的函式，而且可以在該函式內以形式存取實例 thisA reference to the newly allocated instance is automatically passed to the instance constructor and the instance can be accessed from within that constructor as this.

#### 物件初始設定式Object initializers

object_initializer
: '{' member_initializer_list? '}'
| '{' member_initializer_list ',' '}'
;

member_initializer_list
: member_initializer (',' member_initializer)*
;

member_initializer
: initializer_target '=' initializer_value
;

initializer_target
: identifier
| '[' argument_list ']'
;

initializer_value
: expression
| object_or_collection_initializer
;


public class Point
{
int x, y;

public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}


Point a = new Point { X = 0, Y = 1 };


Point __a = new Point();
__a.X = 0;
__a.Y = 1;
Point a = __a;


public class Rectangle
{
Point p1, p2;

public Point P1 { get { return p1; } set { p1 = value; } }
public Point P2 { get { return p2; } set { p2 = value; } }
}


Rectangle r = new Rectangle {
P1 = new Point { X = 0, Y = 1 },
P2 = new Point { X = 2, Y = 3 }
};


Rectangle __r = new Rectangle();
Point __p1 = new Point();
__p1.X = 0;
__p1.Y = 1;
__r.P1 = __p1;
Point __p2 = new Point();
__p2.X = 2;
__p2.Y = 3;
__r.P2 = __p2;
Rectangle r = __r;


If 的函式會配置 Rectangle 兩個內嵌的 Point 實例If Rectangle's constructor allocates the two embedded Point instances

public class Rectangle
{
Point p1 = new Point();
Point p2 = new Point();

public Point P1 { get { return p1; } }
public Point P2 { get { return p2; } }
}


Rectangle r = new Rectangle {
P1 = { X = 0, Y = 1 },
P2 = { X = 2, Y = 3 }
};


Rectangle __r = new Rectangle();
__r.P1.X = 0;
__r.P1.Y = 1;
__r.P2.X = 2;
__r.P2.Y = 3;
Rectangle r = __r;


var c = new C {
x = true,
y = { a = "Hello" },
z = { 1, 2, 3 },
["x"] = 5,
[0,0] = { "a", "b" },
[1,2] = {}
};


C __c = new C();
__c.x = true;
__c.y.a = "Hello";
string __i1 = "x";
__c[__i1] = 5;
int __i2 = 0, __i3 = 0;
int __i4 = 1, __i5 = 2;
var c = __c;


#### 集合初始設定式Collection initializers

collection_initializer
: '{' element_initializer_list '}'
| '{' element_initializer_list ',' '}'
;

element_initializer_list
: element_initializer (',' element_initializer)*
;

element_initializer
: non_assignment_expression
| '{' expression_list '}'
;

expression_list
: expression (',' expression)*
;


List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };


public class Contact
{
string name;
List<string> phoneNumbers = new List<string>();

public string Name { get { return name; } set { name = value; } }

public List<string> PhoneNumbers { get { return phoneNumbers; } }
}


List<Contact>可以建立和初始化，如下所示：A List<Contact> can be created and initialized as follows:

var contacts = new List<Contact> {
new Contact {
Name = "Chris Smith",
PhoneNumbers = { "206-555-0101", "425-882-8080" }
},
new Contact {
Name = "Bob Harris",
PhoneNumbers = { "650-555-0199" }
}
};


var __clist = new List<Contact>();
Contact __c1 = new Contact();
__c1.Name = "Chris Smith";
Contact __c2 = new Contact();
__c2.Name = "Bob Harris";
var contacts = __clist;


#### 陣列建立運算式Array creation expressions

Array_creation_expression 用來建立 array_type 的新實例。An array_creation_expression is used to create a new instance of an array_type.

array_creation_expression
: 'new' non_array_type '[' expression_list ']' rank_specifier* array_initializer?
| 'new' array_type array_initializer
| 'new' rank_specifier array_initializer
;


new int[,] {{0, 1}, {2, 3}, {4, 5}}


new int[3, 2] {{0, 1}, {2, 3}, {4, 5}}


• Expression_list 的維度長度運算式會依序從左至右進行評估。The dimension length expressions of the expression_list are evaluated in order, from left to right. 在評估每個運算式之後，會執行隱含轉換 (隱含 轉換) 為下列其中一種類型： intuintlongulongFollowing evaluation of each expression, an implicit conversion (Implicit conversions) to one of the following types is performed: int, uint, long, ulong. 此清單中的第一個類型會選擇隱含轉換存在。The first type in this list for which an implicit conversion exists is chosen. 如果運算式的評估或後續的隱含轉換造成例外狀況，則不會評估任何進一步的運算式，也不會執行任何進一步的步驟。If evaluation of an expression or the subsequent implicit conversion causes an exception, then no further expressions are evaluated and no further steps are executed.
• 維度長度的計算值會依照下列方式進行驗證。The computed values for the dimension lengths are validated as follows. 如果有一或多個值小於零，則會擲回， System.OverflowException 且不會執行任何進一步的步驟。If one or more of the values are less than zero, a System.OverflowException is thrown and no further steps are executed.
• 配置具有給定維度長度的陣列實例。An array instance with the given dimension lengths is allocated. 如果沒有足夠的記憶體可配置新的實例，則會擲回， System.OutOfMemoryException 且不會執行任何進一步的步驟。If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
• 新陣列實例的所有元素都會初始化為預設值 (預設值) 。All elements of the new array instance are initialized to their default values (Default values).
• 如果陣列建立運算式包含陣列初始化運算式，則會評估陣列初始化運算式中的每個運算式，並將其指派給其對應的陣列元素。If the array creation expression contains an array initializer, then each expression in the array initializer is evaluated and assigned to its corresponding array element. 評估和指派會依照運算式在陣列初始化運算式中的寫入順序來執行，換句話說，專案會以遞增的索引順序初始化，而最右邊的維度會先遞增。The evaluations and assignments are performed in the order the expressions are written in the array initializer—in other words, elements are initialized in increasing index order, with the rightmost dimension increasing first. 如果指定運算式的評估或對應的陣列元素的後續指派造成例外狀況，則不會 (進一步的元素初始化，其餘的元素則會) 其預設值。If evaluation of a given expression or the subsequent assignment to the corresponding array element causes an exception, then no further elements are initialized (and the remaining elements will thus have their default values).

int[][] a = new int[100][];


int[][] a = new int[100][5];        // Error


int[][] a = new int[100][];
for (int i = 0; i < 100; i++) a[i] = new int[5];


int[,] = new int[100, 5];


var a = new[] { 1, 10, 100, 1000 };                       // int[]

var b = new[] { 1, 1.5, 2, 2.5 };                         // double[]

var c = new[,] { { "hello", null }, { "world", "!" } };   // string[,]

var d = new[] { 1, "one", 2, "two" };                     // Error


var contacts = new[] {
new {
Name = "Chris Smith",
PhoneNumbers = new[] { "206-555-0101", "425-882-8080" }
},
new {
Name = "Bob Harris",
PhoneNumbers = new[] { "650-555-0199" }
}
};


#### 委派建立運算式Delegate creation expressions

Delegate_creation_expression 用來建立 delegate_type 的新實例。A delegate_creation_expression is used to create a new instance of a delegate_type.

delegate_creation_expression
: 'new' delegate_type '(' expression ')'
;


• 如果 E 是方法群組，則會使用與方法群組轉換相同的方式來處理委派建立運算式 (方法群組 轉換) 從轉換 EDIf E is a method group, the delegate creation expression is processed in the same way as a method group conversion (Method group conversions) from E to D.
• 如果 E 是匿名函式，則會使用與匿名函式轉換相同的方式來處理委派建立運算式 (從) 到的 匿名 函式轉換 E DIf E is an anonymous function, the delegate creation expression is processed in the same way as an anonymous function conversion (Anonymous function conversions) from E to D.
• 如果 E 是值，就 E 必須與) 的 委派 宣告 (相容， D 而且結果會參考與 D 相同的調用清單所建立之新建立的委派型別 EIf E is a value, E must be compatible (Delegate declarations) with D, and the result is a reference to a newly created delegate of type D that refers to the same invocation list as E. 如果 E 與不相容 D ，就會發生編譯時期錯誤。If E is not compatible with D, a compile-time error occurs.

• 如果 E 是方法群組，則會將委派建立運算式評估為方法群組轉換， (從) 至的 方法群組 轉換 E DIf E is a method group, the delegate creation expression is evaluated as a method group conversion (Method group conversions) from E to D.
• 如果 E 是匿名函式，則會將委派建立評估為的匿名函式轉換， E D) (匿名 函數轉換。If E is an anonymous function, the delegate creation is evaluated as an anonymous function conversion from E to D (Anonymous function conversions).
• 如果 Edelegate_type 的值：If E is a value of a delegate_type:
• E 會進行評估。E is evaluated. 如果此評估造成例外狀況，則不會執行任何進一步的步驟。If this evaluation causes an exception, no further steps are executed.
• 如果的值 Enull ，則會擲回， System.NullReferenceException 且不會執行任何進一步的步驟。If the value of E is null, a System.NullReferenceException is thrown and no further steps are executed.
• 配置委派類型的新實例 DA new instance of the delegate type D is allocated. 如果沒有足夠的記憶體可配置新的實例，則會擲回， System.OutOfMemoryException 且不會執行任何進一步的步驟。If there is not enough memory available to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are executed.
• 新的委派實例初始化時，所使用的調用清單與提供的委派實例相同 EThe new delegate instance is initialized with the same invocation list as the delegate instance given by E.

delegate double DoubleFunc(double x);

class A
{
DoubleFunc f = new DoubleFunc(Square);

static float Square(float x) {
return x * x;
}

static double Square(double x) {
return x * x;
}
}


A.f 欄位會使用參考第二個方法的委派來初始化， Square 因為該方法完全符合的型式參數清單和傳回型別 DoubleFuncthe A.f field is initialized with a delegate that refers to the second Square method because that method exactly matches the formal parameter list and return type of DoubleFunc. 如果有第二個 Square 方法不存在，就會發生編譯時期錯誤。Had the second Square method not been present, a compile-time error would have occurred.

#### 匿名物件建立運算式Anonymous object creation expressions

Anonymous_object_creation_expression 用來建立匿名型別的物件。An anonymous_object_creation_expression is used to create an object of an anonymous type.

anonymous_object_creation_expression
: 'new' anonymous_object_initializer
;

anonymous_object_initializer
: '{' member_declarator_list? '}'
| '{' member_declarator_list ',' '}'
;

member_declarator_list
: member_declarator (',' member_declarator)*
;

member_declarator
: simple_name
| member_access
| base_access
| null_conditional_member_access
| identifier '=' expression
;


new { p1 = e1, p2 = e2, ..., pn = en }


class __Anonymous1
{
...

public __Anonymous1(T1 a1, T2 a2, ..., Tn an) {
f1 = a1;
f2 = a2;
...
fn = an;
}

public T1 p1 { get { return f1; } }
public T2 p2 { get { return f2; } }
...
public Tn pn { get { return fn; } }

public override bool Equals(object __o) { ... }
public override int GetHashCode() { ... }
}


var p1 = new { Name = "Lawnmower", Price = 495.00 };
var p2 = new { Name = "Shovel", Price = 26.95 };
p1 = p2;


Equals GetHashcode 匿名型別上的和方法會覆寫繼承自的方法， object 並且會根據屬性的和來定義 Equals GetHashcode ，如此一來，只有在所有屬性都相等時，相同匿名型別的兩個實例才會相等。The Equals and GetHashcode methods on anonymous types override the methods inherited from object, and are defined in terms of the Equals and GetHashcode of the properties, so that two instances of the same anonymous type are equal if and only if all their properties are equal.

identifier
expr.identifier


identifier = identifier
identifier = expr.identifier


### Typeof 運算子The typeof operator

typeof運算子用來取得 System.Type 類型的物件。The typeof operator is used to obtain the System.Type object for a type.

typeof_expression
: 'typeof' '(' type ')'
| 'typeof' '(' unbound_type_name ')'
| 'typeof' '(' 'void' ')'
;

unbound_type_name
: identifier generic_dimension_specifier?
| identifier '::' identifier generic_dimension_specifier?
| unbound_type_name '.' identifier generic_dimension_specifier?
;

generic_dimension_specifier
: '<' comma* '>'
;

comma
: ','
;


Typeof_expression 的第一種形式是由 typeof 關鍵字後面加上括弧的 別所組成。The first form of typeof_expression consists of a typeof keyword followed by a parenthesized type. 此表單運算式的結果是所 System.Type 指定類型的物件。The result of an expression of this form is the System.Type object for the indicated type. System.Type任何指定的類型只有一個物件。There is only one System.Type object for any given type. 這表示針對型別  Ttypeof(T) == typeof(T) 一律為 true。This means that for a type T, typeof(T) == typeof(T) is always true. 類型 不可為 dynamicThe type cannot be dynamic.

• 藉由將每個 generic_dimension_specifier 取代為 object 每個 type_argument 都有相同數目的逗號和關鍵字，以將每個 type_argument_list 轉換成 type_name。Convert the sequence of tokens to a type_name by replacing each generic_dimension_specifier with a type_argument_list having the same number of commas and the keyword object as each type_argument.
• 評估產生的 type_name，同時忽略所有類型參數條件約束。Evaluate the resulting type_name, while ignoring all type parameter constraints.
• Unbound_type_name 會解析為未系結的泛型型別， (系結 和未系結的型別) ）相關聯。The unbound_type_name resolves to the unbound generic type associated with the resulting constructed type (Bound and unbound types).

Typeof_expression 的結果是產生之未系結 System.Type 泛型型別的物件。The result of the typeof_expression is the System.Type object for the resulting unbound generic type.

typeof運算子可用於類型參數。The typeof operator can be used on a type parameter. 結果是系結 System.Type 至型別參數之執行時間類型的物件。The result is the System.Type object for the run-time type that was bound to the type parameter. typeof運算子也可以用於已建立的型別或未系結的泛型型別， (系結和未系結的類型) 。The typeof operator can also be used on a constructed type or an unbound generic type (Bound and unbound types). 未系結 System.Type 泛型型別的物件與 System.Type 實例類型的物件不同。The System.Type object for an unbound generic type is not the same as the System.Type object of the instance type. 實例型別在執行時間一律是封閉的結構化型別，因此它的 System.Type 物件取決於使用中的執行時間型別引數，而未系結的泛型型別則沒有型別引數。The instance type is always a closed constructed type at run-time so its System.Type object depends on the run-time type arguments in use, while the unbound generic type has no type arguments.

using System;

class X<T>
{
public static void PrintTypes() {
Type[] t = {
typeof(int),
typeof(System.Int32),
typeof(string),
typeof(double[]),
typeof(void),
typeof(T),
typeof(X<T>),
typeof(X<X<T>>),
typeof(X<>)
};
for (int i = 0; i < t.Length; i++) {
Console.WriteLine(t[i]);
}
}
}

class Test
{
static void Main() {
X<int>.PrintTypes();
}
}


System.Int32
System.Int32
System.String
System.Double[]
System.Void
System.Int32
X1[System.Int32]
X1[X1[System.Int32]]
X1[T]


### checked 和 unchecked 運算子The checked and unchecked operators

checkedunchecked 運算子用來控制整數型別算數運算和轉換的 溢位檢查內容The checked and unchecked operators are used to control the overflow checking context for integral-type arithmetic operations and conversions.

checked_expression
: 'checked' '(' expression ')'
;

unchecked_expression
: 'unchecked' '(' expression ')'
;


checked運算子會評估已檢查內容中的包含運算式，而 unchecked 運算子會在未檢查的內容中評估包含的運算式。The checked operator evaluates the contained expression in a checked context, and the unchecked operator evaluates the contained expression in an unchecked context. Checked_expressionunchecked_expression 完全對應至 parenthesized_expression (括弧內的 運算式) ，但包含的運算式會在指定的溢位檢查內容中進行評估。A checked_expression or unchecked_expression corresponds exactly to a parenthesized_expression (Parenthesized expressions), except that the contained expression is evaluated in the given overflow checking context.

• ++ -- 當運算元為整數類資料類型時，預先定義和一元運算子 (後置遞增和遞減運算子，以及前置遞增和遞減運算子) 。The predefined ++ and -- unary operators (Postfix increment and decrement operators and Prefix increment and decrement operators), when the operand is of an integral type.
• -當運算元為整數類資料類型時，預先定義的一元運算子 (一元減號運算子) 。The predefined - unary operator (Unary minus operator), when the operand is of an integral type.
• + - * / 當兩個運算元都是整數類資料類型時，預先定義的、、和二元運算子 (算術運算子) 。The predefined +, -, *, and / binary operators (Arithmetic operators), when both operands are of integral types.
• 明確數值轉換 (明確數值轉換) 從一個整數類型到另一個整數類型，或從 float 或轉換 double 成整數類資料類型。Explicit numeric conversions (Explicit numeric conversions) from one integral type to another integral type, or from float or double to an integral type.

• checked 內容中，如果作業是常數運算式 (常數 運算式) ，就會發生編譯時期錯誤。In a checked context, if the operation is a constant expression (Constant expressions), a compile-time error occurs. 否則，當作業在執行時間執行時， System.OverflowException 就會擲回。Otherwise, when the operation is performed at run-time, a System.OverflowException is thrown.
• unchecked 內容中，會捨棄不符合目的地類型的任何高序位位，藉以截斷結果。In an unchecked context, the result is truncated by discarding any high-order bits that do not fit in the destination type.

class Test
{
static readonly int x = 1000000;
static readonly int y = 1000000;

static int F() {
return checked(x * y);      // Throws OverflowException
}

static int G() {
return unchecked(x * y);    // Returns -727379968
}

static int H() {
return x * y;               // Depends on default
}
}


class Test
{
const int x = 1000000;
const int y = 1000000;

static int F() {
return checked(x * y);      // Compile error, overflow
}

static int G() {
return unchecked(x * y);    // Returns -727379968
}

static int H() {
return x * y;               // Compile error, overflow
}
}


checkedunchecked 運算子只會對包含在 " ( " 和 "" 標記內以程式集中的作業，影響溢位檢查內容 )The checked and unchecked operators only affect the overflow checking context for those operations that are textually contained within the "(" and ")" tokens. 運算子不會影響在評估包含的運算式時所叫用的函數成員。The operators have no effect on function members that are invoked as a result of evaluating the contained expression. 在範例中In the example

class Test
{
static int Multiply(int x, int y) {
return x * y;
}

static int F() {
return checked(Multiply(1000000, 1000000));
}
}


checked在中使用 F 並不會影響中的評估 x * y Multiply ，因此 x * y 會在預設溢位檢查內容中進行評估。the use of checked in F does not affect the evaluation of x * y in Multiply, so x * y is evaluated in the default overflow checking context.

unchecked在十六進位標記法中撰寫帶正負號整數類資料類型的常數時，運算子會很方便。The unchecked operator is convenient when writing constants of the signed integral types in hexadecimal notation. 例如：For example:

class Test
{
public const int AllBits = unchecked((int)0xFFFFFFFF);

public const int HighBit = unchecked((int)0x80000000);
}


checkedunchecked 運算子和語句可讓程式設計人員控制一些數值計算的特定層面。The checked and unchecked operators and statements allow programmers to control certain aspects of some numeric calculations. 不過，某些數值運算子的行為取決於其運算元的資料類型。However, the behavior of some numeric operators depends on their operands' data types. 例如，即使在明確的結構內，兩個小數位數一律會導致溢位例外狀況 uncheckedFor example, multiplying two decimals always results in an exception on overflow even within an explicitly unchecked construct. 同樣地，即使在明確的結構內，將兩個浮點數相乘也不會造成溢位例外狀況 checkedSimilarly, multiplying two floats never results in an exception on overflow even within an explicitly checked construct. 此外，其他運算子永遠不會受到檢查模式的影響，不論是預設或明確。In addition, other operators are never affected by the mode of checking, whether default or explicit.

### 預設值運算式Default value expressions

default_value_expression
: 'default' '(' type ')'
;


### Nameof 運算式Nameof expressions

Nameof_expression 用來取得程式實體的名稱，做為常數位串。A nameof_expression is used to obtain the name of a program entity as a constant string.

nameof_expression
: 'nameof' '(' named_entity ')'
;

named_entity
: simple_name
| named_entity_target '.' identifier type_argument_list?
;

named_entity_target
: 'this'
| 'base'
| named_entity
| predefined_type
| qualified_alias_member
;


Nameof_expressionnamed_entity 意義就是運算式的意義;也就是 simple_namebase_accessmember_accessThe meaning of the named_entity of a nameof_expression is the meaning of it as an expression; that is, either as a simple_name, a base_access or a member_access. 不過，在 簡單名稱成員存取 中描述的查閱會導致錯誤，因為在靜態內容中找到實例成員，所以 nameof_expression 不會產生這類錯誤。However, where the lookup described in Simple names and Member access results in an error because an instance member was found in a static context, a nameof_expression produces no such error.

Nameof_expression 是類型的常數運算式 string ，在執行時間不會有任何作用。A nameof_expression is a constant expression of type string, and has no effect at runtime. 具體來說，它的 named_entity 不會進行評估，而且會基於明確指派分析的用途而忽略 () 簡單運算式的一般規則Specifically, its named_entity is not evaluated, and is ignored for the purposes of definite assignment analysis (General rules for simple expressions). 它的值是選擇性最終 type_argument_list 之前 named_entity 的最後一個識別碼，轉換方式如下：Its value is the last identifier of the named_entity before the optional final type_argument_list, transformed in the following way:

• 移除前置詞 " @ " （如果使用的話）。The prefix "@", if used, is removed.
• 每個 unicode_escape_sequence 都會轉換成其對應的 unicode 字元。Each unicode_escape_sequence is transformed into its corresponding Unicode character.
• 移除任何 formatting_charactersAny formatting_characters are removed.

TODO：範例TODO: examples

### 匿名方法運算式Anonymous method expressions

Anonymous_method_expression 是定義匿名函式的兩種方式之一。An anonymous_method_expression is one of two ways of defining an anonymous function. 這些會在匿名函式 運算式中進一步說明。These are further described in Anonymous function expressions.

## 一元運算子Unary operators

、、、、、、 ? + - ! ~ ++ -- 、Cast 和 await 運算子稱為一元運算子。The ?, +, -, !, ~, ++, --, cast, and await operators are called the unary operators.

unary_expression
: primary_expression
| null_conditional_expression
| '+' unary_expression
| '-' unary_expression
| '!' unary_expression
| '~' unary_expression
| pre_increment_expression
| pre_decrement_expression
| cast_expression
| await_expression
| unary_expression_unsafe
;


### Null 條件運算子Null-conditional operator

Null 條件運算子只會在運算元為非 null 時，才會將作業清單套用至其運算元。The null-conditional operator applies a list of operations to its operand only if that operand is non-null. 否則，套用運算子的結果為 nullOtherwise the result of applying the operator is null.

null_conditional_expression
: primary_expression null_conditional_operations
;

null_conditional_operations
: null_conditional_operations? '?' '.' identifier type_argument_list?
| null_conditional_operations? '?' '[' argument_list ']'
| null_conditional_operations '.' identifier type_argument_list?
| null_conditional_operations '[' argument_list ']'
| null_conditional_operations '(' argument_list? ')'
;


E0E1 可用來判斷的意義 EE0 and E1 are used to determine the meaning of E:

• 如果 E 發生做為 statement_expression 的意義 E 就與語句相同If E occurs as a statement_expression the meaning of E is the same as the statement

if ((object)P != null) E1;


但只會評估 P 一次。except that P is evaluated only once.

• 否則，如果 E0 分類為任何未發生的編譯時期錯誤，則為。Otherwise, if E0 is classified as nothing a compile-time error occurs.

• 否則，請讓 T0 成為的型別 E0Otherwise, let T0 be the type of E0.

• 如果 T0 是不知道為參考型別或不可為 null 實值型別的型別參數，則會發生編譯時期錯誤。If T0 is a type parameter that is not known to be a reference type or a non-nullable value type, a compile-time error occurs.

• 如果 T0 是不可為 null 的實值型別，則的型別 ET0? ，且的意義 EIf T0 is a non-nullable value type, then the type of E is T0?, and the meaning of E is the same as

((object)P == null) ? (T0?)null : E1


P 只會評估一次。except that P is evaluated only once.

• 否則，E 的類型為 T0，而 E 的意義與Otherwise the type of E is T0, and the meaning of E is the same as

((object)P == null) ? null : E1


P 只會評估一次。except that P is evaluated only once.

a.b?[0]?.c();


if (a.b != null) a.b[0]?.c();


if (a.b != null) if (a.b[0] != null) a.b[0].c();


var x = a.b?[0]?.c();


var x = (a.b == null) ? null : (a.b[0] == null) ? null : a.b[0].c();


#### Null 條件運算式作為投影初始化運算式Null-conditional expressions as projection initializers

Null 條件運算式只允許做為 anonymous_object_creation_expression (匿名物件建立運算式member_declarator ，) 如果它的結尾是 (選擇性的 null 條件式) 成員存取。A null-conditional expression is only allowed as a member_declarator in an anonymous_object_creation_expression (Anonymous object creation expressions) if it ends with an (optionally null-conditional) member access. 文法，此需求可表示為：Grammatically, this requirement can be expressed as:

null_conditional_member_access
: primary_expression null_conditional_operations? '?' '.' identifier type_argument_list?
| primary_expression null_conditional_operations '.' identifier type_argument_list?
;


#### Null 條件運算式作為語句運算式Null-conditional expressions as statement expressions

Null 條件運算式只允許做為 statement_expression 的 (運算式語句) 如果其結尾是調用。A null-conditional expression is only allowed as a statement_expression (Expression statements) if it ends with an invocation. 文法，此需求可表示為：Grammatically, this requirement can be expressed as:

null_conditional_invocation_expression
: primary_expression null_conditional_operations '(' argument_list? ')'
;


### 一元加號運算子Unary plus operator

int operator +(int x);
uint operator +(uint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
double operator +(double x);
decimal operator +(decimal x);


### 一元減號運算子Unary minus operator

• 整數否定：Integer negation:

int operator -(int x);
long operator -(long x);


結果的計算方式是 x 從零減去。The result is computed by subtracting x from zero. 如果的值 x 是運算元類型的最小可表示值 (-2 ^ 31 代表 int 或-2 ^ 63 表示 long) ，則在 x 運算元類型內無法表示的數學否定。If the value of x is the smallest representable value of the operand type (-2^31 for int or -2^63 for long), then the mathematical negation of x is not representable within the operand type. 如果發生這種情況 checked ，就會擲回， System.OverflowException 如果它發生在 unchecked 內容中，結果就是運算元的值，而且不會報告溢位。If this occurs within a checked context, a System.OverflowException is thrown; if it occurs within an unchecked context, the result is the value of the operand and the overflow is not reported.

如果負運算子的運算元是型別，則 uint 會轉換成類型 long ，而結果的型別為 longIf the operand of the negation operator is of type uint, it is converted to type long, and the type of the result is long. 例外狀況是允許將 int 值-2147483648 (-2 ^ 31) 撰寫為) 整數常 值的十進位 (整數常值的規則。An exception is the rule that permits the int value -2147483648 (-2^31) to be written as a decimal integer literal (Integer literals).

如果負運算子的運算元是型別 ulong ，就會發生編譯階段錯誤。If the operand of the negation operator is of type ulong, a compile-time error occurs. 例外狀況是允許將 long 值-9223372036854775808 (-2 ^ 63) 撰寫為) 整數常 值的十進位整數 (常值的規則。An exception is the rule that permits the long value -9223372036854775808 (-2^63) to be written as a decimal integer literal (Integer literals).

• 浮點數否定：Floating-point negation:

float operator -(float x);
double operator -(double x);


結果會是 x 其正負號反轉的值。The result is the value of x with its sign inverted. 如果 x 是 nan，則結果也是 nan。If x is NaN, the result is also NaN.

• 小數否定：Decimal negation:

decimal operator -(decimal x);


結果的計算方式是 x 從零減去。The result is computed by subtracting x from zero. Decimal 負號相當於使用類型的一元減號運算子 System.DecimalDecimal negation is equivalent to using the unary minus operator of type System.Decimal.

### 邏輯否定運算子Logical negation operator

bool operator !(bool x);


### 位元補充運算子 Bitwise complement operator

int operator ~(int x);
uint operator ~(uint x);
long operator ~(long x);
ulong operator ~(ulong x);


E operator ~(E x);


### 前置遞增和遞減運算子Prefix increment and decrement operators

pre_increment_expression
: '++' unary_expression
;

pre_decrement_expression
: '--' unary_expression
;


• 如果 x 分類為變數：If x is classified as a variable:
• x 會評估以產生變數。x is evaluated to produce the variable.
• 使用的值 x 做為其引數來叫用選取的運算子。The selected operator is invoked with the value of x as its argument.
• 運算子所傳回的值會儲存在評估所指定的位置 xThe value returned by the operator is stored in the location given by the evaluation of x.
• 運算子傳回的值會成為作業的結果。The value returned by the operator becomes the result of the operation.
• 如果 x 分類為屬性或索引子存取：If x is classified as a property or indexer access:
• 如果不是) ，實例運算式 (x static ，且如果 x 是與相關聯的索引子存取) ，則會評估引數 (清單 x ，且結果會用於後續 getset 存取子調用。The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent get and set accessor invocations.
• 叫用的 get 存取子 xThe get accessor of x is invoked.
• 使用存取子所傳回的值 get 做為其引數，以叫用選取的運算子。The selected operator is invoked with the value returned by the get accessor as its argument.
• set 存取子 x 會以運算子傳回的值做為其引數來叫用 valueThe set accessor of x is invoked with the value returned by the operator as its value argument.
• 運算子傳回的值會成為作業的結果。The value returned by the operator becomes the result of the operation.

++-- 運算子也支援後置標記法 (後置遞增和遞減運算子) 。The ++ and -- operators also support postfix notation (Postfix increment and decrement operators). 或的結果通常是在作業 x++ x-- 之前的值 x ，而或的結果 ++x 是作業之後的 --xxTypically, the result of x++ or x-- is the value of x before the operation, whereas the result of ++x or --x is the value of x after the operation. 在任一種情況下， x 其本身在作業之後都具有相同的值。In either case, x itself has the same value after the operation.

operator++ operator-- 可以使用後置或前置標記法來叫用或實作為。An operator++ or operator-- implementation can be invoked using either postfix or prefix notation. 這兩種標記法不能有個別的運算子實現。It is not possible to have separate operator implementations for the two notations.

### 轉換運算式Cast expressions

Cast_expression 用來明確地將運算式轉換成指定的型別。A cast_expression is used to explicitly convert an expression to a given type.

cast_expression
: '(' type ')' unary_expression
;


Cast_expression 的文法會導致特定的語法歧義。The grammar for a cast_expression leads to certain syntactic ambiguities. 例如，您 (x)-y 可以將運算式解釋為 cast_expression (將轉換為 -y 類型 x) 或 additive_expression 與計算值的 parenthesized_expression (結合 x - y)For example, the expression (x)-y could either be interpreted as a cast_expression (a cast of -y to type x) or as an additive_expression combined with a parenthesized_expression (which computes the value x - y).

• 標記的序列是 類型 的正確文法，但不是 運算式 的正確文法。The sequence of tokens is correct grammar for a type, but not for an expression.
• Token 的順序是正確的 別文法，而緊接在右括弧後面的 token 是 token " ~ "、token " ! "、token " ( "、 (Unicode 字元 escape 序列) 的 識別碼 值 (值) 或任何 關鍵字 (關鍵字) 除了 as 和之外 isThe sequence of tokens is correct grammar for a type, and the token immediately following the closing parentheses is the token "~", the token "!", the token "(", an identifier (Unicode character escape sequences), a literal (Literals), or any keyword (Keywords) except as and is.

### Await 運算式Await expressions

Await 運算子用來暫止封閉非同步函式的評估，直到運算元所表示的非同步作業完成為止。The await operator is used to suspend evaluation of the enclosing async function until the asynchronous operation represented by the operand has completed.

await_expression
: 'await' unary_expression
;


Await_expression 只能在非同步函式的主體中使用 (非同步函式) 。An await_expression is only allowed in the body of an async function (Async functions). 在最接近的封入非同步函式內， await_expression 可能不會出現在這些位置：Within the nearest enclosing async function, an await_expression may not occur in these places:

• 在嵌套 (非非同步) 匿名函式中Inside a nested (non-async) anonymous function
• lock_statement 的區塊內Inside the block of a lock_statement
• 在 unsafe 內容中In an unsafe context

Await_expression 的運算元稱為 *task _。The operand of an await_expression is called the *task _. 它代表在評估 _await_expression * 時，可能或可能不會完成的非同步作業。It represents an asynchronous operation that may or may not be complete at the time the _await_expression* is evaluated. Await 運算子的目的是暫停執行封閉的非同步函式，直到等候的工作完成，然後取得其結果。The purpose of the await operator is to suspend execution of the enclosing async function until the awaited task is complete, and then obtain its outcome.

#### 可等候運算式Awaitable expressions

• t 是編譯時間類型 dynamict is of compile time type dynamic
• t 具有可存取的實例或 GetAwaiter 使用不含參數的擴充方法，而且沒有任何型別參數，以及下列所有的傳回型 A 別：t has an accessible instance or extension method called GetAwaiter with no parameters and no type parameters, and a return type A for which all of the following hold:
• ASystem.Runtime.CompilerServices.INotifyCompletion為了簡潔起見，會實 (的介面 INotifyCompletion) A implements the interface System.Runtime.CompilerServices.INotifyCompletion (hereafter known as INotifyCompletion for brevity)
• A具有類型的可存取、可讀取的實例屬性 IsCompletedboolA has an accessible, readable instance property IsCompleted of type bool
• A 具有 GetResult 無參數且沒有類型參數的可存取的實例方法A has an accessible instance method GetResult with no parameters and no type parameters

#### Await 運算式的執行時間評估Runtime evaluation of await expressions

• a 由評估運算式來取得 awaiter (t).GetAwaiter()An awaiter a is obtained by evaluating the expression (t).GetAwaiter().
• bool b 由評估運算式來取得 (a).IsCompletedA bool b is obtained by evaluating the expression (a).IsCompleted.
• 如果 b 為， false 則評估取決於是否 a 執行介面 (接下來 System.Runtime.CompilerServices.ICriticalNotifyCompletion 稱為 ICriticalNotifyCompletion 以求簡潔) 。If b is false then evaluation depends on whether a implements the interface System.Runtime.CompilerServices.ICriticalNotifyCompletion (hereafter known as ICriticalNotifyCompletion for brevity). 這項檢查是在系結階段完成;也就是在執行時間 a 中，如果有編譯時間類型，則為 dynamic ，否則為。This check is done at binding time; i.e. at runtime if a has the compile time type dynamic, and at compile time otherwise. r) 的 (非同步 函式表示繼續委派：Let r denote the resumption delegate (Async functions):
• 如果 a 未執行 ICriticalNotifyCompletion ，則 (a as (INotifyCompletion)).OnCompleted(r) 會評估運算式。If a does not implement ICriticalNotifyCompletion, then the expression (a as (INotifyCompletion)).OnCompleted(r) is evaluated.
• 如果 a 確實執行 ICriticalNotifyCompletion ，則 (a as (ICriticalNotifyCompletion)).UnsafeOnCompleted(r) 會評估運算式。If a does implement ICriticalNotifyCompletion, then the expression (a as (ICriticalNotifyCompletion)).UnsafeOnCompleted(r) is evaluated.
• 然後評估會暫停，控制權會傳回給 async 函式的目前呼叫者。Evaluation is then suspended, and control is returned to the current caller of the async function.
• 在 (if) 之後 b ，或在稍後叫用繼續 true 委派 (如果 b false) ，則 (a).GetResult() 會評估運算式。Either immediately after (if b was true), or upon later invocation of the resumption delegate (if b was false), the expression (a).GetResult() is evaluated. 如果它傳回值，該值就是 await_expression 的結果。If it returns a value, that value is the result of the await_expression. 否則結果為 nothing。Otherwise the result is nothing.

## 算術運算子Arithmetic operators

*、、 / %+- 運算子稱為算術運算子。The *, /, %, +, and - operators are called the arithmetic operators.

multiplicative_expression
: unary_expression
| multiplicative_expression '*' unary_expression
| multiplicative_expression '/' unary_expression
| multiplicative_expression '%' unary_expression
;

: multiplicative_expression
;


### 乘法運算子Multiplication operator

• 整數乘法：Integer multiplication:

int operator *(int x, int y);
uint operator *(uint x, uint y);
long operator *(long x, long y);
ulong operator *(ulong x, ulong y);


checked 內容中，如果產品超出結果型別的範圍， System.OverflowException 就會擲回。In a checked context, if the product is outside the range of the result type, a System.OverflowException is thrown. unchecked 內容中，不會報告溢位，而且會捨棄結果型別範圍之外的任何大量高序位位。In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

• 浮點數乘法：Floating-point multiplication:

float operator *(float x, float y);
double operator *(double x, double y);


會根據 IEEE 754 算術的規則來計算產品。The product is computed according to the rules of IEEE 754 arithmetic. 下表列出非零有限值、零、無限大和 NaN 所有可能組合的結果。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 在下表中，xy 是正有限值。In the table, x and y are positive finite values. zx * y 的結果。z is the result of x * y. 如果結果對目的地類型而言太大，則 z 為無限大。If the result is too large for the destination type, z is infinity. 如果結果對目的地類型而言太小，則 z 為零。If the result is too small for the destination type, z is zero.

+y+y -y-y +0+0 -0-0 +inf+inf -inf-inf NaNNaN
+x+x +z+z -Z-z +0+0 -0-0 +inf+inf -inf-inf NaNNaN
-X-x -Z-z +z+z -0-0 +0+0 -inf-inf +inf+inf NaNNaN
+0+0 +0+0 -0-0 +0+0 -0-0 NaNNaN NaNNaN NaNNaN
-0-0 -0-0 +0+0 -0-0 +0+0 NaNNaN NaNNaN NaNNaN
+inf+inf +inf+inf -inf-inf NaNNaN NaNNaN +inf+inf -inf-inf NaNNaN
-inf-inf -inf-inf +inf+inf NaNNaN NaNNaN -inf-inf +inf+inf NaNNaN
NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
• 十進位乘法：Decimal multiplication:

decimal operator *(decimal x, decimal y);


如果產生的值太大而無法以格式表示 decimalSystem.OverflowException 就會擲回。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 如果結果值太小而無法以 decimal 格式表示，則結果為零。If the result value is too small to represent in the decimal format, the result is zero. 結果的小數位數是在任何四捨五入之前，這是兩個運算元之刻度的總和。The scale of the result, before any rounding, is the sum of the scales of the two operands.

Decimal 乘法相當於使用類型的乘法運算子 System.DecimalDecimal multiplication is equivalent to using the multiplication operator of type System.Decimal.

### 除法運算子Division operator

• 整數除法：Integer division:

int operator /(int x, int y);
uint operator /(uint x, uint y);
long operator /(long x, long y);
ulong operator /(ulong x, ulong y);


如果右運算元的值為零， System.DivideByZeroException 則會擲回。If the value of the right operand is zero, a System.DivideByZeroException is thrown.

相除會將結果四捨五入至零。The division rounds the result towards zero. 因此，結果的絕對值會是小於或等於兩個運算元之商絕對值的最大可能整數。Thus the absolute value of the result is the largest possible integer that is less than or equal to the absolute value of the quotient of the two operands. 當兩個運算元的正負號相同時，如果兩個運算元具有相同的正負號，則結果為零或正數。The result is zero or positive when the two operands have the same sign and zero or negative when the two operands have opposite signs.

如果左運算元是最小的可 int long 表示值或值，右邊的運算元為 -1 ，就會發生溢位。If the left operand is the smallest representable int or long value and the right operand is -1, an overflow occurs. checked 內容中，這會造成 System.ArithmeticException) 擲回 (或子類別。In a checked context, this causes a System.ArithmeticException (or a subclass thereof) to be thrown. unchecked 內容中，它會在執行時定義為是否擲 System.ArithmeticException 回 (或子類別) ，或溢位未報告，且結果值為左運算元的值。In an unchecked context, it is implementation-defined as to whether a System.ArithmeticException (or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand.

• 浮點數除法：Floating-point division:

float operator /(float x, float y);
double operator /(double x, double y);


商會根據 IEEE 754 算術的規則來計算。The quotient is computed according to the rules of IEEE 754 arithmetic. 下表列出非零有限值、零、無限大和 NaN 所有可能組合的結果。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 在下表中，xy 是正有限值。In the table, x and y are positive finite values. zx / y 的結果。z is the result of x / y. 如果結果對目的地類型而言太大，則 z 為無限大。If the result is too large for the destination type, z is infinity. 如果結果對目的地類型而言太小，則 z 為零。If the result is too small for the destination type, z is zero.

+y+y -y-y +0+0 -0-0 +inf+inf -inf-inf NaNNaN
+x+x +z+z -Z-z +inf+inf -inf-inf +0+0 -0-0 NaNNaN
-X-x -Z-z +z+z -inf-inf +inf+inf -0-0 +0+0 NaNNaN
+0+0 +0+0 -0-0 NaNNaN NaNNaN +0+0 -0-0 NaNNaN
-0-0 -0-0 +0+0 NaNNaN NaNNaN -0-0 +0+0 NaNNaN
+inf+inf +inf+inf -inf-inf +inf+inf -inf-inf NaNNaN NaNNaN NaNNaN
-inf-inf -inf-inf +inf+inf -inf-inf +inf+inf NaNNaN NaNNaN NaNNaN
NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
• 小數除法：Decimal division:

decimal operator /(decimal x, decimal y);


如果右運算元的值為零， System.DivideByZeroException 則會擲回。If the value of the right operand is zero, a System.DivideByZeroException is thrown. 如果產生的值太大而無法以格式表示 decimalSystem.OverflowException 就會擲回。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 如果結果值太小而無法以 decimal 格式表示，則結果為零。If the result value is too small to represent in the decimal format, the result is zero. 結果的小數位數是將結果等於最接近的可表示十進位值的最小小數位數。The scale of the result is the smallest scale that will preserve a result equal to the nearest representable decimal value to the true mathematical result.

小數除法相當於使用類型的除法運算子 System.DecimalDecimal division is equivalent to using the division operator of type System.Decimal.

### 餘數運算子Remainder operator

• 整數餘數：Integer remainder:

int operator %(int x, int y);
uint operator %(uint x, uint y);
long operator %(long x, long y);
ulong operator %(ulong x, ulong y);


的結果 x % y 是所產生的值 x - (x / y) * yThe result of x % y is the value produced by x - (x / y) * y. 如果 y 為零， System.DivideByZeroException 則會擲回。If y is zero, a System.DivideByZeroException is thrown.

如果左運算元是最小 int 值或 long 值，右邊運算元是 -1System.OverflowException 則會擲回。If the left operand is the smallest int or long value and the right operand is -1, a System.OverflowException is thrown. 在沒有任何情況下 x % y ，會擲回例外狀況， x / y 而不會擲回例外狀況。In no case does x % y throw an exception where x / y would not throw an exception.

• 浮點數餘數：Floating-point remainder:

float operator %(float x, float y);
double operator %(double x, double y);


下表列出非零有限值、零、無限大和 NaN 所有可能組合的結果。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 在下表中，xy 是正有限值。In the table, x and y are positive finite values. zx % y 和計算的結果 x - n * y ，其中 n 是小於或等於的最大可能整數 x / yz is the result of x % y and is computed as x - n * y, where n is the largest possible integer that is less than or equal to x / y. 這種計算餘數的方法與用於整數運算元的方法類似，但不同于 IEEE 754 定義 (， n 也就是最接近) 的整數 x / yThis method of computing the remainder is analogous to that used for integer operands, but differs from the IEEE 754 definition (in which n is the integer closest to x / y).

+y+y -y-y +0+0 -0-0 +inf+inf -inf-inf NaNNaN
+x+x +z+z +z+z NaNNaN NaNNaN xx xx NaNNaN
-X-x -Z-z -Z-z NaNNaN NaNNaN -X-x -X-x NaNNaN
+0+0 +0+0 +0+0 NaNNaN NaNNaN +0+0 +0+0 NaNNaN
-0-0 -0-0 -0-0 NaNNaN NaNNaN -0-0 -0-0 NaNNaN
+inf+inf NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
-inf-inf NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
• 小數餘數：Decimal remainder:

decimal operator %(decimal x, decimal y);


如果右運算元的值為零， System.DivideByZeroException 則會擲回。If the value of the right operand is zero, a System.DivideByZeroException is thrown. 在任何四捨五入之前，結果的小數位數是兩個運算元的最大刻度，而結果的正負號（如果非零）則與相同 xThe scale of the result, before any rounding, is the larger of the scales of the two operands, and the sign of the result, if non-zero, is the same as that of x.

小數餘數相當於使用類型的餘數運算子 System.DecimalDecimal remainder is equivalent to using the remainder operator of type System.Decimal.

int operator +(int x, int y);
uint operator +(uint x, uint y);
long operator +(long x, long y);
ulong operator +(ulong x, ulong y);


checked 內容中，如果總和超出結果型別的範圍， System.OverflowException 就會擲回。In a checked context, if the sum is outside the range of the result type, a System.OverflowException is thrown. unchecked 內容中，不會報告溢位，而且會捨棄結果型別範圍之外的任何大量高序位位。In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

float operator +(float x, float y);
double operator +(double x, double y);


總和是根據 IEEE 754 算術的規則來計算。The sum is computed according to the rules of IEEE 754 arithmetic. 下表列出非零有限值、零、無限大和 NaN 所有可能組合的結果。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaN's. 在下表中，xy 是非零有限值，而 zx + y 的結果。In the table, x and y are nonzero finite values, and z is the result of x + y. 如果 xy 具有相同的大小，但正負號相反，則 z 為正零。If x and y have the same magnitude but opposite signs, z is positive zero. 如果 x + y 太大而無法在目的地類型中表示， z 則為具有相同正負號的無限大 x + yIf x + y is too large to represent in the destination type, z is an infinity with the same sign as x + y.

yy +0+0 -0-0 +inf+inf -inf-inf NaNNaN
xx zz xx xx +inf+inf -inf-inf NaNNaN
+0+0 yy +0+0 +0+0 +inf+inf -inf-inf NaNNaN
-0-0 yy +0+0 -0-0 +inf+inf -inf-inf NaNNaN
+inf+inf +inf+inf +inf+inf +inf+inf +inf+inf NaNNaN NaNNaN
-inf-inf -inf-inf -inf-inf -inf-inf NaNNaN -inf-inf NaNNaN
NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN

decimal operator +(decimal x, decimal y);


如果產生的值太大而無法以格式表示 decimalSystem.OverflowException 就會擲回。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 在任何四捨五入之前，結果的小數位數是兩個運算元的尺規越大。The scale of the result, before any rounding, is the larger of the scales of the two operands.

Decimal 加法相當於使用類型的加法運算子 System.DecimalDecimal addition is equivalent to using the addition operator of type System.Decimal.

• 列舉加法。Enumeration addition. 每個列舉型別都會隱含地提供下列預先定義的運算子，其中 E 是列舉型別，而 U 是的基礎型別 EEvery enumeration type implicitly provides the following predefined operators, where E is the enum type, and U is the underlying type of E:

E operator +(E x, U y);
E operator +(U x, E y);


在執行時間，這些運算子的評估方式完全相同 (E)((U)x + (U)y)At run-time these operators are evaluated exactly as (E)((U)x + (U)y).

• 字串串連：String concatenation:

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);


二元運算子的這些多載會 + 執行字串串連。These overloads of the binary + operator perform string concatenation. 如果字串串連的運算元是 null ，則會取代空字串。If an operand of string concatenation is null, an empty string is substituted. 否則，任何非字串引數都會叫用繼承自類型的虛擬方法，以轉換成其字串表示 ToString objectOtherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. 如果 ToString 傳回 null ，則會取代空字串。If ToString returns null, an empty string is substituted.

using System;

class Test
{
static void Main() {
string s = null;
Console.WriteLine("s = >" + s + "<");        // displays s = ><
int i = 1;
Console.WriteLine("i = " + i);               // displays i = 1
float f = 1.2300E+15F;
Console.WriteLine("f = " + f);               // displays f = 1.23E+15
decimal d = 2.900m;
Console.WriteLine("d = " + d);               // displays d = 2.900
}
}


字串串連運算子的結果是一個字串，其中包含左運算元的字元以及右運算元的字元。 字串串連運算子永遠不會傳回 null 值。 System.OutOfMemoryException如果沒有足夠的記憶體可配置結果字串，可能會擲回。A System.OutOfMemoryException may be thrown if there is not enough memory available to allocate the resulting string.

• 委派組合。Delegate combination. 每個委派型別都會隱含地提供下列預先定義的運算子，其中 D 是委派型別：Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

D operator +(D x, D y);


二元 + 運算子會在兩個運算元都屬於某個委派型別時，執行委派組合 DThe binary + operator performs delegate combination when both operands are of some delegate type D. (如果運算元有不同的委派類型，就會發生系結時期錯誤。 ) 如果第一個運算元是，則作業的 null 結果會是第二個運算元的值 (即使也 null) 。(If the operands have different delegate types, a binding-time error occurs.) If the first operand is null, the result of the operation is the value of the second operand (even if that is also null). 否則，如果第二個運算元是 null ，則運算的結果會是第一個運算元的值。Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. 否則，作業的結果會是新的委派實例，當叫用它時，會叫用第一個運算元，然後叫用第二個運算元。Otherwise, the result of the operation is a new delegate instance that, when invoked, invokes the first operand and then invokes the second operand. 如需委派組合的範例，請參閱 減法運算子委派調用For examples of delegate combination, see Subtraction operator and Delegate invocation. 由於不是 System.Delegate 委派型別， operator  + 因此不會為它定義。Since System.Delegate is not a delegate type, operator + is not defined for it.

### 減法運算子Subtraction operator

• 整數減法：Integer subtraction:

int operator -(int x, int y);
uint operator -(uint x, uint y);
long operator -(long x, long y);
ulong operator -(ulong x, ulong y);


checked 內容中，如果差異超出結果型別的範圍， System.OverflowException 就會擲回。In a checked context, if the difference is outside the range of the result type, a System.OverflowException is thrown. unchecked 內容中，不會報告溢位，而且會捨棄結果型別範圍之外的任何大量高序位位。In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.

• 浮點數減法：Floating-point subtraction:

float operator -(float x, float y);
double operator -(double x, double y);


差異是根據 IEEE 754 算術的規則來計算。The difference is computed according to the rules of IEEE 754 arithmetic. 下表列出所有可能的非零有限值、零、無限大和 Nan 組合的結果。The following table lists the results of all possible combinations of nonzero finite values, zeros, infinities, and NaNs. 在下表中，xy 是非零有限值，而 zx - y 的結果。In the table, x and y are nonzero finite values, and z is the result of x - y. 如果 xy 相等，則 z 為正零。If x and y are equal, z is positive zero. 如果 x - y 太大而無法在目的地類型中表示， z 則為具有相同正負號的無限大 x - yIf x - y is too large to represent in the destination type, z is an infinity with the same sign as x - y.

yy +0+0 -0-0 +inf+inf -inf-inf NaNNaN
xx zz xx xx -inf-inf +inf+inf NaNNaN
+0+0 -y-y +0+0 +0+0 -inf-inf +inf+inf NaNNaN
-0-0 -y-y -0-0 +0+0 -inf-inf +inf+inf NaNNaN
+inf+inf +inf+inf +inf+inf +inf+inf NaNNaN +inf+inf NaNNaN
-inf-inf -inf-inf -inf-inf -inf-inf -inf-inf NaNNaN NaNNaN
NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN NaNNaN
• 十進位減法：Decimal subtraction:

decimal operator -(decimal x, decimal y);


如果產生的值太大而無法以格式表示 decimalSystem.OverflowException 就會擲回。If the resulting value is too large to represent in the decimal format, a System.OverflowException is thrown. 在任何四捨五入之前，結果的小數位數是兩個運算元的尺規越大。The scale of the result, before any rounding, is the larger of the scales of the two operands.

Decimal 減法相當於使用類型的減法運算子 System.DecimalDecimal subtraction is equivalent to using the subtraction operator of type System.Decimal.

• 列舉減法。Enumeration subtraction. 每個列舉型別都會隱含地提供下列預先定義的運算子，其中 E 是列舉型別，而 U 是的基礎型別 EEvery enumeration type implicitly provides the following predefined operator, where E is the enum type, and U is the underlying type of E:

U operator -(E x, E y);


這個運算子的評估方式完全相同 (U)((U)x - (U)y)This operator is evaluated exactly as (U)((U)x - (U)y). 換句話說，運算子會計算和的序數值之間的差異 x y ，而結果的型別則是列舉的基礎類型。In other words, the operator computes the difference between the ordinal values of x and y, and the type of the result is the underlying type of the enumeration.

E operator -(E x, U y);


這個運算子的評估方式完全相同 (E)((U)x - y)This operator is evaluated exactly as (E)((U)x - y). 換句話說，運算子會從列舉的基礎類型減去值，並產生列舉的值。In other words, the operator subtracts a value from the underlying type of the enumeration, yielding a value of the enumeration.

• 委派移除。Delegate removal. 每個委派型別都會隱含地提供下列預先定義的運算子，其中 D 是委派型別：Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

D operator -(D x, D y);


二元 - 運算子會在兩個運算元都屬於某個委派類型時，執行委派移除 DThe binary - operator performs delegate removal when both operands are of some delegate type D. 如果運算元有不同的委派類型，就會發生系結階段錯誤。If the operands have different delegate types, a binding-time error occurs. 如果第一個運算元是 null，則作業的結果是 nullIf the first operand is null, the result of the operation is null. 否則，如果第二個運算元是 null ，則運算的結果會是第一個運算元的值。Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. 否則，這兩個運算元代表具有一個或多個專案的調用清單 () 委派 宣告，而結果是新的調用清單，其中包含第一個運算元的清單，其中包含第二個運算元的專案，前提是第二個運算元的清單是第一個運算元的適當連續子清單。Otherwise, both operands represent invocation lists (Delegate declarations) having one or more entries, and the result is a new invocation list consisting of the first operand's list with the second operand's entries removed from it, provided the second operand's list is a proper contiguous sublist of the first's. (判斷子清單是否相等，對應的專案會與委派等號比較運算子的比較， (委派等 號比較運算子) ) 。否則，結果就是左運算元的值。(To determine sublist equality, corresponding entries are compared as for the delegate equality operator (Delegate equality operators).) Otherwise, the result is the value of the left operand. 進程中的兩個運算元清單都沒有變更。Neither of the operands' lists is changed in the process. 如果第二個運算元的清單與第一個運算元清單中連續專案的多個清單子相符，則會移除最右邊相符的連續專案子清單。If the second operand's list matches multiple sublists of contiguous entries in the first operand's list, the right-most matching sublist of contiguous entries is removed. 如果移除導致空白清單，則結果是 nullIf removal results in an empty list, the result is null. 例如：For example:

delegate void D(int x);

class C
{
public static void M1(int i) { /* ... */ }
public static void M2(int i) { /* ... */ }
}

class Test
{
static void Main() {
D cd1 = new D(C.M1);
D cd2 = new D(C.M2);
D cd3 = cd1 + cd2 + cd2 + cd1;   // M1 + M2 + M2 + M1
cd3 -= cd1;                      // => M1 + M2 + M2

cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
cd3 -= cd1 + cd2;                // => M2 + M1

cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
cd3 -= cd2 + cd2;                // => M1 + M1

cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
cd3 -= cd2 + cd1;                // => M1 + M2

cd3 = cd1 + cd2 + cd2 + cd1;     // M1 + M2 + M2 + M1
cd3 -= cd1 + cd1;                // => M1 + M2 + M2 + M1
}
}


## 移位運算子Shift operators

<<>> 運算子用來執行位移位作業。The << and >> operators are used to perform bit shifting operations.

shift_expression
;


• 左移：Shift left:

int operator <<(int x, int count);
uint operator <<(uint x, int count);
long operator <<(long x, int count);
ulong operator <<(ulong x, int count);


<<運算子會 x 向左移一些計算的位數，如下所述。The << operator shifts x left by a number of bits computed as described below.

會捨棄結果型別範圍之外的高序位位 x ，其餘的位會左移，而且低序位空白位位置會設定為零。The high-order bits outside the range of the result type of x are discarded, the remaining bits are shifted left, and the low-order empty bit positions are set to zero.

• 右移：Shift right:

int operator >>(int x, int count);
uint operator >>(uint x, int count);
long operator >>(long x, int count);
ulong operator >>(ulong x, int count);


>>運算子會 x 由計算的位數右移，如下所述。The >> operator shifts x right by a number of bits computed as described below.

x 的型別為 int 或時 long ，會捨棄的低序位位 x ，其餘的位會右移，而且如果 x 是負數，則高序位的空白位位置會設定為零 xWhen x is of type int or long, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero if x is non-negative and set to one if x is negative.

x 的類型為 uint 或時 ulong ，會捨棄的低序位位 x ，其餘的位會右移，而高序位的空白位位置會設定為零。When x is of type uint or ulong, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero.

• 當的型別 xint 或時 uint ，會由的低序位五位指定移位元數目 countWhen the type of x is int or uint, the shift count is given by the low-order five bits of count. 換句話說，會從計算移位元數目 count & 0x1FIn other words, the shift count is computed from count & 0x1F.
• 當的型別 xlong 或時 ulong ，會由的低序位六位指定移位元數目 countWhen the type of x is long or ulong, the shift count is given by the low-order six bits of count. 換句話說，會從計算移位元數目 count & 0x3FIn other words, the shift count is computed from count & 0x3F.

## 關係和類型測試運算子Relational and type-testing operators

、、、、、 == != < > <= >= isas 運算子稱為關聯式和型別測試運算子。The ==, !=, <, >, <=, >=, is and as operators are called the relational and type-testing operators.

relational_expression
: shift_expression
| relational_expression '<' shift_expression
| relational_expression '>' shift_expression
| relational_expression '<=' shift_expression
| relational_expression '>=' shift_expression
| relational_expression 'is' type
| relational_expression 'as' type
;

equality_expression
: relational_expression
| equality_expression '==' relational_expression
| equality_expression '!=' relational_expression
;


is運算子會在 as 運算子描述，而 as 運算子則是在as 運算子中描述。The is operator is described in The is operator and the as operator is described in The as operator.

==、、 != <> <=>= 運算子為 比較運算子The ==, !=, <, >, <= and >= operators are comparison operators.

x == y true 如果 x 等於，則為 yfalse 否則為。true if x is equal to y, false otherwise
x != y true 如果不 x 等於，則為 yfalse 否則為。true if x is not equal to y, false otherwise
x < y x 小於 y 則為 true；否則為 falsetrue if x is less than y, false otherwise
x > y x 大於 y 則為 true；否則為 falsetrue if x is greater than y, false otherwise
x <= y x 小於或等於 y 則為 true；否則為 falsetrue if x is less than or equal to y, false otherwise
x >= y x 大於或等於 y 則為 true；否則為 falsetrue if x is greater than or equal to y, false otherwise

### 整數比較運算子Integer comparison operators

bool operator ==(int x, int y);
bool operator ==(uint x, uint y);
bool operator ==(long x, long y);
bool operator ==(ulong x, ulong y);

bool operator !=(int x, int y);
bool operator !=(uint x, uint y);
bool operator !=(long x, long y);
bool operator !=(ulong x, ulong y);

bool operator <(int x, int y);
bool operator <(uint x, uint y);
bool operator <(long x, long y);
bool operator <(ulong x, ulong y);

bool operator >(int x, int y);
bool operator >(uint x, uint y);
bool operator >(long x, long y);
bool operator >(ulong x, ulong y);

bool operator <=(int x, int y);
bool operator <=(uint x, uint y);
bool operator <=(long x, long y);
bool operator <=(ulong x, ulong y);

bool operator >=(int x, int y);
bool operator >=(uint x, uint y);
bool operator >=(long x, long y);
bool operator >=(ulong x, ulong y);


### 浮點數比較運算子Floating-point comparison operators

bool operator ==(float x, float y);
bool operator ==(double x, double y);

bool operator !=(float x, float y);
bool operator !=(double x, double y);

bool operator <(float x, float y);
bool operator <(double x, double y);

bool operator >(float x, float y);
bool operator >(double x, double y);

bool operator <=(float x, float y);
bool operator <=(double x, double y);

bool operator >=(float x, float y);
bool operator >=(double x, double y);


• 如果任一個運算元為 NaN，則結果為 false 所有運算子 != ，但結果為 trueIf either operand is NaN, the result is false for all operators except !=, for which the result is true. 針對任何兩個運算元， x != y 一律會產生與相同的結果 !(x == y)For any two operands, x != y always produces the same result as !(x == y). 不過，當一個或兩個運算元都是 NaN 時， <><=>= 運算子不會產生與相反運算子的邏輯否定相同的結果。However, when one or both operands are NaN, the <, >, <=, and >= operators do not produce the same results as the logical negation of the opposite operator. 例如，如果的任一個 x y 是 NaN，則為 x < y false ，但 !(x >= y)trueFor example, if either of x and y is NaN, then x < y is false, but !(x >= y) is true.

• 當兩個運算元都不是 NaN 時，運算子會比較兩個浮點數運算元的值與順序相關When neither operand is NaN, the operators compare the values of the two floating-point operands with respect to the ordering

-inf < -max < ... < -min < -0.0 == +0.0 < +min < ... < +max < +inf


其中 minmax 是可依給定浮點數格式表示的最小和最大正有限值。where min and max are the smallest and largest positive finite values that can be represented in the given floating-point format. 此順序值得注意的影響如下：Notable effects of this ordering are:

• 負零和正零會視為相等。Negative and positive zeros are considered equal.
• 負無限大會被視為小於所有其他值，但等於另一個負無限大。A negative infinity is considered less than all other values, but equal to another negative infinity.
• 正無限大視為大於所有其他值，但等於另一個正無限大。A positive infinity is considered greater than all other values, but equal to another positive infinity.

### 小數比較運算子Decimal comparison operators

bool operator ==(decimal x, decimal y);
bool operator !=(decimal x, decimal y);
bool operator <(decimal x, decimal y);
bool operator >(decimal x, decimal y);
bool operator <=(decimal x, decimal y);
bool operator >=(decimal x, decimal y);


### 布林等號比較運算子Boolean equality operators

bool operator ==(bool x, bool y);
bool operator !=(bool x, bool y);


### 列舉比較運算子Enumeration comparison operators

bool operator ==(E x, E y);
bool operator !=(E x, E y);
bool operator <(E x, E y);
bool operator >(E x, E y);
bool operator <=(E x, E y);
bool operator >=(E x, E y);


### 參考型別等號比較運算子Reference type equality operators

bool operator ==(object x, object y);
bool operator !=(object x, object y);


• 這兩個運算元都是已知為 reference_type 或常值之類型的值 nullBoth operands are a value of a type known to be a reference_type or the literal null. 此外，明確參考轉換 (明確參考 轉換) 存在於任一運算元的類型與另一個運算元的類型之間。Furthermore, an explicit reference conversion (Explicit reference conversions) exists from the type of either operand to the type of the other operand.
• 其中一個運算元是型別的值， T 其中 Ttype_parameter ，另一個運算元是常值 nullOne operand is a value of type T where T is a type_parameter and the other operand is the literal null. 此外 T ，也沒有實數值型別條件約束。Furthermore T does not have the value type constraint.

• 這是系結階段錯誤，可使用預先定義的參考型別等號比較運算子來比較已知在系結時間不同的兩個參考。It is a binding-time error to use the predefined reference type equality operators to compare two references that are known to be different at binding-time. 例如，如果運算元的系結時間型別是兩個類別型別 AB 而且也不是 A B 衍生自另一個類別，則這兩個運算元將無法參考相同的物件。For example, if the binding-time types of the operands are two class types A and B, and if neither A nor B derives from the other, then it would be impossible for the two operands to reference the same object. 因此，作業會被視為系結階段錯誤。Thus, the operation is considered a binding-time error.
• 預先定義的參考型別等號比較運算子不允許比較實值型別運算元。The predefined reference type equality operators do not permit value type operands to be compared. 因此，除非結構類型宣告自己的等號比較運算子，否則不可能比較該結構類型的值。Therefore, unless a struct type declares its own equality operators, it is not possible to compare values of that struct type.
• 預先定義的參考型別等號比較運算子永遠不會導致其運算元發生「裝箱」作業。The predefined reference type equality operators never cause boxing operations to occur for their operands. 執行這類的裝箱作業並不具意義，因為對新配置的已封裝實例的參考必須與其他所有參考不同。It would be meaningless to perform such boxing operations, since references to the newly allocated boxed instances would necessarily differ from all other references.
• 如果將類型參數類型的運算元 T 與進行比較 null ，且執行時間類型為實 T 值型別，則比較結果為 falseIf an operand of a type parameter type T is compared to null, and the run-time type of T is a value type, the result of the comparison is false.

class C<T>
{
void F(T x) {
if (x == null) throw new ArgumentNullException();
...
}
}


x == null即使可以表示實值型別，也可以使用此結構 T ，而結果只是定義為 falseT 值型別。The x == null construct is permitted even though T could represent a value type, and the result is simply defined to be false when T is a value type.

using System;

class Test
{
static void Main() {
string s = "Test";
string t = string.Copy(s);
Console.WriteLine(s == t);
Console.WriteLine((object)s == t);
Console.WriteLine(s == (object)t);
Console.WriteLine((object)s == (object)t);
}
}


True
False
False
False


st 變數參考兩個不同 string 的實例，其中包含相同的字元。The s and t variables refer to two distinct string instances containing the same characters. 第一個比較輸出的原因是， True 當兩個運算元的類型為時，會選取預先定義的字串相等運算子 (字串相等運算子) stringThe first comparison outputs True because the predefined string equality operator (String equality operators) is selected when both operands are of type string. 其餘的比較會比較所有輸出 False ，因為當其中一個或兩個運算元的類型為時，會選取預先定義的參考型別等號比較運算子 objectThe remaining comparisons all output False because the predefined reference type equality operator is selected when one or both of the operands are of type object.

class Test
{
static void Main() {
int i = 123;
int j = 123;
System.Console.WriteLine((object)i == (object)j);
}
}


### 字串等號比較運算子String equality operators

bool operator ==(string x, string y);
bool operator !=(string x, string y);


string當下列其中一項為真時，兩個值會被視為相等：Two string values are considered equal when one of the following is true:

• 這兩個值都是 nullBoth values are null.
• 這兩個值都是在每個字元位置都有相同長度和相同字元之字串實例的非 null 參考。Both values are non-null references to string instances that have identical lengths and identical characters in each character position.

### 委派等號比較運算子Delegate equality operators

bool operator ==(System.Delegate x, System.Delegate y);
bool operator !=(System.Delegate x, System.Delegate y);


• 如果其中一個委派實例為 null ，則它們都相等，而且只有在兩者皆為時 nullIf either of the delegate instances is null, they are equal if and only if both are null.
• 如果委派有不同的執行時間類型，它們永遠不會相等。If the delegates have different run-time type they are never equal.
• 如果這兩個委派實例都有一個調用清單 (委派 宣告) ，則只有在其調用清單的長度相同，且一個調用清單中的每個專案都 (等於對應專案（依序在其他的調用清單中）) 對應專案的情況下，才會相等。If both of the delegate instances have an invocation list (Delegate declarations), those instances are equal if and only if their invocation lists are the same length, and each entry in one's invocation list is equal (as defined below) to the corresponding entry, in order, in the other's invocation list.

• 如果兩個調用清單專案都參考相同的靜態方法，則專案會相等。If two invocation list entries both refer to the same static method then the entries are equal.
• 如果兩個調用清單專案都參考相同目標物件上的相同非靜態方法 (如參考等號比較運算子所定義) 則專案相等。If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal.
• 在以語義相同的 anonymous_method_expression s 或 lambda_expression s 的評估所產生的調用清單專案中，具有相同 (可能會有空白) 的已捕捉外部變數實例集 (但不需要) 相等。Invocation list entries produced from evaluation of semantically identical anonymous_method_expression s or lambda_expression s with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal.

### 等號比較運算子和 nullEquality operators and null

==And != 運算子允許一個運算元成為可為 null 型別的值，另一個運算元為 null 常值，即使沒有任何預先定義或使用者定義的運算子 (在 unlifted 或提升表單中) 存在於作業中。The == and != operators permit one operand to be a value of a nullable type and the other to be the null literal, even if no predefined or user-defined operator (in unlifted or lifted form) exists for the operation.

x == null
null == x
x != null
null != x


### is 運算子The is operator

is運算子用來動態檢查物件的執行時間類型是否與指定的類型相容。The is operator is used to dynamically check if the run-time type of an object is compatible with a given type. 作業的結果 E is T （其中 E 是運算式且 T 為型別）是一個布林值，指出是否可以透過 E T 參考轉換、裝箱轉換或取消加入的轉換，成功地將轉換成型別。The result of the operation E is T, where E is an expression and T is a type, is a boolean value indicating whether E can successfully be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion. 在將型別引數替換為所有型別參數之後，此作業會評估如下：The operation is evaluated as follows, after type arguments have been substituted for all type parameters:

• 如果 E 是匿名函式，就會發生編譯時期錯誤If E is an anonymous function, a compile-time error occurs
• 如果 E 是方法群組或 null 常值，如果的類型 E 是參考型別或可為 null 的型別，而且的值 E 為 null，則結果為 false。If E is a method group or the null literal, of if the type of E is a reference type or a nullable type and the value of E is null, the result is false.
• 否則，讓我們 D 以如下方式表示動態類型 EOtherwise, let D represent the dynamic type of E as follows:
• 如果的型別 E 是參考型別， D 則是實例參考的執行時間型別 EIf the type of E is a reference type, D is the run-time type of the instance reference by E.
• 如果的型別 E 是可為 null 的型別， D 就是可為 null 型別的基礎型別。If the type of E is a nullable type, D is the underlying type of that nullable type.
• 如果的型別 E 是不可為 null 的實值型別， D 就是的型別 EIf the type of E is a non-nullable value type, D is the type of E.
• 作業的結果取決於和，如下所示 D TThe result of the operation depends on D and T as follows:
• 如果 T 是參考型別，則如果 D 和是 T 相同的型別，而且如果 D 是的參考型別和從的隱含參考轉換 D T ，或者是實值型別， D 而且從轉換 D 成 exists 的 T ，則結果為 true。If T is a reference type, the result is true if D and T are the same type, if D is a reference type and an implicit reference conversion from D to T exists, or if D is a value type and a boxing conversion from D to T exists.
• 如果 T 是可為 null 的型別，則如果 D 是的基礎型別，則結果為 true TIf T is a nullable type, the result is true if D is the underlying type of T.
• 如果 T 是不可為 null 的實值型別，則如果 D 和是相同的型別，則結果為 true TIf T is a non-nullable value type, the result is true if D and T are the same type.
• 否則，結果為 false。Otherwise, the result is false.

### as 運算子The as operator

as運算子用來將值明確轉換為指定的參考型別或可為 null 的型別。The as operator is used to explicitly convert a value to a given reference type or nullable type. 不同于 cast 運算式 (cast 運算式) ， as 運算子永遠不會擲回例外狀況。Unlike a cast expression (Cast expressions), the as operator never throws an exception. 相反地，如果無法指定轉換，則產生的值為 nullInstead, if the indicated conversion is not possible, the resulting value is null.

E is T ? (T)(E) : (T)null


E is T ? (T)(object)(E) : (T)null


class X
{

public string F(object o) {
return o as string;        // OK, string is a reference type
}

public T G<T>(object o) where T: Attribute {
return o as T;             // Ok, T has a class constraint
}

public U H<U>(object o) {
return o as U;             // Error, U is unconstrained
}
}


## 邏輯運算子Logical operators

&^| 運算子稱為邏輯運算子。The &, ^, and | operators are called the logical operators.

and_expression
: equality_expression
| and_expression '&' equality_expression
;

exclusive_or_expression
: and_expression
| exclusive_or_expression '^' and_expression
;

inclusive_or_expression
: exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression
;


### 整數邏輯運算子Integer logical operators

int operator &(int x, int y);
uint operator &(uint x, uint y);
long operator &(long x, long y);
ulong operator &(ulong x, ulong y);

int operator |(int x, int y);
uint operator |(uint x, uint y);
long operator |(long x, long y);
ulong operator |(ulong x, ulong y);

int operator ^(int x, int y);
uint operator ^(uint x, uint y);
long operator ^(long x, long y);
ulong operator ^(ulong x, ulong y);


&運算子會計算兩個運算元的位邏輯 AND ，運算子會計算兩個運算元的位邏輯 | OR ，而 ^ 運算子會計算兩個運算元的位邏輯互斥 ORThe & operator computes the bitwise logical AND of the two operands, the | operator computes the bitwise logical OR of the two operands, and the ^ operator computes the bitwise logical exclusive OR of the two operands. 這些作業不可能有溢位。No overflows are possible from these operations.

### 列舉邏輯運算子Enumeration logical operators

E operator &(E x, E y);
E operator |(E x, E y);
E operator ^(E x, E y);


### 布林值邏輯運算子Boolean logical operators

bool operator &(bool x, bool y);
bool operator |(bool x, bool y);
bool operator ^(bool x, bool y);


xy 皆為 true，那麼 x & y 的結果會是 trueThe result of x & y is true if both x and y are true. 否則，結果為 falseOtherwise, the result is false.

x | y true 如果 xy 為，則的結果為 trueThe result of x | y is true if either x or y is true. 否則，結果為 falseOtherwise, the result is false.

### 可為 null 的布林值邏輯運算子Nullable boolean logical operators

bool? operator &(bool? x, bool? y);
bool? operator |(bool? x, bool? y);


x y x & y x | y
true true true true
true false false true
true null null true
false true false true
false false false false
false null false null
null true null true
null false false null
null null null null

## 條件邏輯運算子Conditional logical operators

&&|| 運算子稱為條件邏輯運算子。The && and || operators are called the conditional logical operators. 它們也稱為「短路」邏輯運算子。They are also called the "short-circuiting" logical operators.

conditional_and_expression
: inclusive_or_expression
| conditional_and_expression '&&' inclusive_or_expression
;

conditional_or_expression
: conditional_and_expression
| conditional_or_expression '||' conditional_and_expression
;


&&|| 運算子是和運算子的條件式 & 版本 |The && and || operators are conditional versions of the & and | operators:

• 作業會 x && y 對應至作業 x & y ，但只有在 y 不是時才會評估 x falseThe operation x && y corresponds to the operation x & y, except that y is evaluated only if x is not false.
• 作業會 x || y 對應至作業 x | y ，但只有在 y 不是時才會評估 x trueThe operation x || y corresponds to the operation x | y, except that y is evaluated only if x is not true.

• 如果多載解析找不到單一最佳運算子，或多載解析選取其中一個預先定義的整數邏輯運算子，則會發生系結階段錯誤。If overload resolution fails to find a single best operator, or if overload resolution selects one of the predefined integer logical operators, a binding-time error occurs.
• 否則，如果選取的運算子是其中一個預先定義的布林值邏輯運算子 (布林值邏輯 運算子) 或可為 null 的布林值邏輯運算子 (可為 null 的布林值邏輯運算子) ，則會如 布林條件邏輯運算子中所述處理作業。Otherwise, if the selected operator is one of the predefined boolean logical operators (Boolean logical operators) or nullable boolean logical operators (Nullable boolean logical operators), the operation is processed as described in Boolean conditional logical operators.
• 否則，選取的運算子是使用者定義的運算子，且作業會依照 使用者定義的條件式邏輯運算子中的說明進行處理。Otherwise, the selected operator is a user-defined operator, and the operation is processed as described in User-defined conditional logical operators.

### 布林條件邏輯運算子Boolean conditional logical operators

• 運算 x && y 會評估為 x ? y : falseThe operation x && y is evaluated as x ? y : false. 換句話說， x 會先進行評估，並轉換成型別 boolIn other words, x is first evaluated and converted to type bool. 然後，如果 xtruey 則會評估並轉換成類型 bool ，而這會成為作業的結果。Then, if x is true, y is evaluated and converted to type bool, and this becomes the result of the operation. 否則，作業的結果為 falseOtherwise, the result of the operation is false.
• 運算 x || y 會評估為 x ? true : yThe operation x || y is evaluated as x ? true : y. 換句話說， x 會先進行評估，並轉換成型別 boolIn other words, x is first evaluated and converted to type bool. 然後，如果 x 是，則作業的 true 結果為 trueThen, if x is true, the result of the operation is true. 否則， y 會進行評估並轉換成類型 bool ，而這會成為作業的結果。Otherwise, y is evaluated and converted to type bool, and this becomes the result of the operation.

### 使用者定義條件式邏輯運算子User-defined conditional logical operators

• 所選運算子的傳回類型和每個參數的類型必須是 TThe return type and the type of each parameter of the selected operator must be T. 換句話說，運算子必須計算 AND 兩個型別運算元的邏輯 or 邏輯 OR T ，而且必須傳回型別的結果 TIn other words, the operator must compute the logical AND or the logical OR of two operands of type T, and must return a result of type T.
• T 必須包含和的 operator true 宣告 operator falseT must contain declarations of operator true and operator false.

• 作業 x && y 會評估為 T.false(x) ? x : T.&(x, y) ，其中 T.false(x) 是在中宣告的調用， operator false T 而且 T.&(x, y) 是所選的調用 operator &The operation x && y is evaluated as T.false(x) ? x : T.&(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&(x, y) is an invocation of the selected operator &. 換句話說， x 會先進行評估，並 operator false 在結果上叫用，以判斷是否 x 肯定為 false。In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. 然後，如果 x 肯定為 false，則作業的結果會是先前針對所計算的值 xThen, if x is definitely false, the result of the operation is the value previously computed for x. 否則， y 會進行評估，並 operator & 在先前計算的值上叫用選取的值， x 並針對所計算的值，以產生作業的 y 結果。Otherwise, y is evaluated, and the selected operator & is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.
• 作業 x || y 會評估為 T.true(x) ? x : T.|(x, y) ，其中 T.true(x) 是在中宣告的調用， operator true T 而且 T.|(x,y) 是所選的調用 operator|The operation x || y is evaluated as T.true(x) ? x : T.|(x, y), where T.true(x) is an invocation of the operator true declared in T, and T.|(x,y) is an invocation of the selected operator|. 換句話說， x 會先進行評估，並 operator true 在結果上叫用，以判斷是否 x 為絕對 true。In other words, x is first evaluated and operator true is invoked on the result to determine if x is definitely true. 然後，如果 x 肯定是 true，則作業的結果會是先前針對所計算的值 xThen, if x is definitely true, the result of the operation is the value previously computed for x. 否則， y 會進行評估，並 operator | 在先前計算的值上叫用選取的值， x 並針對所計算的值，以產生作業的 y 結果。Otherwise, y is evaluated, and the selected operator | is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.

## Null 聯合運算子The null coalescing operator

??運算子稱為 null 聯合運算子。The ?? operator is called the null coalescing operator.

null_coalescing_expression
: conditional_or_expression
| conditional_or_expression '??' null_coalescing_expression
;


Null 聯合運算子是右向關聯的，表示作業是由右至左分組。The null coalescing operator is right-associative, meaning that operations are grouped from right to left. 例如，表單的運算式 a ?? b ?? c 會評估為 a ?? (b ?? c)For example, an expression of the form a ?? b ?? c is evaluated as a ?? (b ?? c). 一般情況下，表單的運算式 E1 ?? E2 ?? ... ?? En 會傳回非 null 的第一個運算元，如果所有運算元都是 null，則為 null。In general terms, an expression of the form E1 ?? E2 ?? ... ?? En returns the first of the operands that is non-null, or null if all operands are null.

• 如果 A 存在，而且不是可為 null 的型別或參考型別，就會發生編譯時期錯誤。If A exists and is not a nullable type or a reference type, a compile-time error occurs.
• 如果 b 是動態運算式，則結果類型為 dynamicIf b is a dynamic expression, the result type is dynamic. 在執行時間， a 會先評估。At run-time, a is first evaluated. 如果不 a 是 null， a 則會轉換為動態，而這會成為結果。If a is not null, a is converted to dynamic, and this becomes the result. 否則， b 會進行評估，而這會成為結果。Otherwise, b is evaluated, and this becomes the result.
• 否則，如果 A 存在，而且是可為 null 的型別，而且有隱含轉換 b A0 ，則結果類型為 A0Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. 在執行時間， a 會先評估。At run-time, a is first evaluated. 如果不 a 是 null， a 則會解除包裝為類型 A0 ，而這會成為結果。If a is not null, a is unwrapped to type A0, and this becomes the result. 否則， b 會進行評估並轉換成類型 A0 ，而這會成為結果。Otherwise, b is evaluated and converted to type A0, and this becomes the result.
• 否則，如果 A 存在，而且有隱含轉換 b ，則 A 結果類型為 AOtherwise, if A exists and an implicit conversion exists from b to A, the result type is A. 在執行時間， a 會先評估。At run-time, a is first evaluated. 如果不 a 是 null， a 就會成為結果。If a is not null, a becomes the result. 否則， b 會進行評估並轉換成類型 A ，而這會成為結果。Otherwise, b is evaluated and converted to type A, and this becomes the result.
• 否則，如果的 b 類型 B 和隱含轉換存在 aB ，則結果類型為 BOtherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. 在執行時間， a 會先評估。At run-time, a is first evaluated. 如果不 a 是 null， a 則會將解除包裝為類型 A0 (如果存在，而且可為 A null) 並且轉換為類型，則會 B 變成結果。If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. 否則， b 會進行評估並成為結果。Otherwise, b is evaluated and becomes the result.
• 否則， ab 不相容，而且會發生編譯時期錯誤。Otherwise, a and b are incompatible, and a compile-time error occurs.

## 條件運算子Conditional operator

?:運算子稱為條件運算子。The ?: operator is called the conditional operator. 它有時也稱為三元運算子。It is at times also called the ternary operator.

conditional_expression
: null_coalescing_expression
| null_coalescing_expression '?' expression ':' expression
;


• 如果 x 有型別 X ，而且 y 有型別 Y thenIf x has type X and y has type Y then
• 如果隱含轉換 (隱含 轉換) 存在於 XY ，而不是從轉換為，則 Y X Y 是條件運算式的類型。If an implicit conversion (Implicit conversions) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
• 如果隱含轉換 (隱含 轉換) 存在於 YX ，而不是從轉換為，則 X Y X 是條件運算式的類型。If an implicit conversion (Implicit conversions) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.
• 否則，就不能判斷任何運算式型別，而且會發生編譯時期錯誤。Otherwise, no expression type can be determined, and a compile-time error occurs.
• 如果只有一個 xy 具有型別，而且和兩者都可以隱含地 x y 轉換成該型別，則這是條件運算式的型別。If only one of x and y has a type, and both x and y, of are implicitly convertible to that type, then that is the type of the conditional expression.
• 否則，就不能判斷任何運算式型別，而且會發生編譯時期錯誤。Otherwise, no expression type can be determined, and a compile-time error occurs.

• 首先， b 會進行評估，並 bool 決定的值 bFirst, b is evaluated, and the bool value of b is determined:
• 如果從的型別隱含轉換 b bool 存在，則會執行這項隱含轉換來產生 bool 值。If an implicit conversion from the type of b to bool exists, then this implicit conversion is performed to produce a bool value.
• 否則，會叫用的型別所 operator true 定義的 b 來產生 bool 值。Otherwise, the operator true defined by the type of b is invoked to produce a bool value.
• 如果 bool 上述步驟所產生的值為 true ，則 x 會進行評估並轉換成條件運算式的類型，而這會成為條件運算式的結果。If the bool value produced by the step above is true, then x is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression.
• 否則， y 會進行評估並轉換成條件運算式的類型，而這會成為條件運算式的結果。Otherwise, y is evaluated and converted to the type of the conditional expression, and this becomes the result of the conditional expression.

## 匿名函式運算式Anonymous function expressions

lambda_expression
: anonymous_function_signature '=>' anonymous_function_body
;

anonymous_method_expression
: 'delegate' explicit_anonymous_function_signature? block
;

anonymous_function_signature
: explicit_anonymous_function_signature
| implicit_anonymous_function_signature
;

explicit_anonymous_function_signature
: '(' explicit_anonymous_function_parameter_list? ')'
;

explicit_anonymous_function_parameter_list
: explicit_anonymous_function_parameter (',' explicit_anonymous_function_parameter)*
;

explicit_anonymous_function_parameter
: anonymous_function_parameter_modifier? type identifier
;

anonymous_function_parameter_modifier
: 'ref'
| 'out'
;

implicit_anonymous_function_signature
: '(' implicit_anonymous_function_parameter_list? ')'
| implicit_anonymous_function_parameter
;

implicit_anonymous_function_parameter_list
: implicit_anonymous_function_parameter (',' implicit_anonymous_function_parameter)*
;

implicit_anonymous_function_parameter
: identifier
;

anonymous_function_body
: expression
| block
;


=>運算子的優先順序與指派 (=) 相同，而且是右向關聯。The => operator has the same precedence as assignment (=) and is right-associative.

( param ) => expr


param => expr


x => x + 1                              // Implicitly typed, expression body
x => { return x + 1; }                  // Implicitly typed, statement body
(int x) => x + 1                        // Explicitly typed, expression body
(int x) => { return x + 1; }            // Explicitly typed, statement body
(x, y) => x * y                         // Multiple parameters
() => Console.WriteLine()               // No parameters
async (t1,t2) => await t1 + await t2    // Async
delegate (int x) { return x + 1; }      // Anonymous method expression
delegate { return 1 + 1; }              // Parameter list omitted


• anonymous_method_expression 允許完全省略參數清單，產生可轉換性來委派任何值參數清單的類型。anonymous_method_expression s permit the parameter list to be omitted entirely, yielding convertibility to delegate types of any list of value parameters.
• lambda_expression 允許省略和推斷參數類型，而 anonymous_method_expression s 則需要明確陳述參數類型。lambda_expression s permit parameter types to be omitted and inferred whereas anonymous_method_expression s require parameter types to be explicitly stated.
• Lambda_expression 的主體可以是運算式或語句區塊，而 anonymous_method_expression 的主體必須是語句區塊。The body of a lambda_expression can be an expression or a statement block whereas the body of an anonymous_method_expression must be a statement block.
• 只有 lambda_expression s 會轉換成相容的運算式樹狀架構類型 (運算式樹狀架構類型) 。Only lambda_expression s have conversions to compatible expression tree types (Expression tree types).

### 匿名函數主體Anonymous function bodies

• 如果匿名函式包含簽章，則簽章中指定的參數會出現在主體中。If the anonymous function includes a signature, the parameters specified in the signature are available in the body. 如果匿名函式沒有簽章，則可以將參數轉換成具有參數 (匿名函式 轉換) 的委派類型或運算式類型，但無法在主體中存取參數。If the anonymous function has no signature it can be converted to a delegate type or expression type having parameters (Anonymous function conversions), but the parameters cannot be accessed in the body.
• 除了簽 refout 中指定的或參數 (如果最接近的封入匿名函式有任何) ，就會發生編譯時期錯誤，主體才可存取 refout 參數。Except for ref or out parameters specified in the signature (if any) of the nearest enclosing anonymous function, it is a compile-time error for the body to access a ref or out parameter.
• 當的型別 this 是結構類型時，就是要存取主體的編譯時期錯誤 thisWhen the type of this is a struct type, it is a compile-time error for the body to access this. 無論存取是否明確 (如 this.x) 或隱含 (一樣，例如 x where x 是結構) 的實例成員。This is true whether the access is explicit (as in this.x) or implicit (as in x where x is an instance member of the struct). 此規則只會禁止這類存取，而且不會影響成員查閱結果是否在結構的成員中。This rule simply prohibits such access and does not affect whether member lookup results in a member of the struct.
• 主體可存取匿名函式 (外部 變數) 外部變數。The body has access to the outer variables (Outer variables) of the anonymous function. 外部變數的存取權將會參考 lambda_expressionanonymous_method_expression (評估時使用中的變數實例，) 匿名函數運算式的評估Access of an outer variable will reference the instance of the variable that is active at the time the lambda_expression or anonymous_method_expression is evaluated (Evaluation of anonymous function expressions).
• 這是一個編譯時期錯誤，主體包含的 goto 語句、 break 語句或 continue 語句的目標是在主體外部，或在包含的匿名函式主體內。It is a compile-time error for the body to contain a goto statement, break statement, or continue statement whose target is outside the body or within the body of a contained anonymous function.
• return主體中的語句會從最接近的封入匿名函式的調用傳回控制權，而不是從封入函數成員傳回。A return statement in the body returns control from an invocation of the nearest enclosing anonymous function, not from the enclosing function member. 語句中指定的運算式 return 必須可以隱含地轉換成委派型別或運算式樹狀結構型別的傳回型別，也就是最接近的封入 lambda_expressionanonymous_method_expression 轉換 (匿名函數轉換) 。An expression specified in a return statement must be implicitly convertible to the return type of the delegate type or expression tree type to which the nearest enclosing lambda_expression or anonymous_method_expression is converted (Anonymous function conversions).

### 多載解析和匿名函數Overload resolution and anonymous functions

class ItemList<T>: List<T>
{
public int Sum(Func<T,int> selector) {
int sum = 0;
foreach (T item in this) sum += selector(item);
return sum;
}

public double Sum(Func<T,double> selector) {
double sum = 0;
foreach (T item in this) sum += selector(item);
return sum;
}
}


ItemList<T>類別有兩種 Sum 方法。The ItemList<T> class has two Sum methods. 每個都採用 selector 引數，它會從清單專案中解壓縮值以加總。Each takes a selector argument, which extracts the value to sum over from a list item. 解壓縮的值可以是 intdouble ，而且產生的總和同樣是 intdoubleThe extracted value can be either an int or a double and the resulting sum is likewise either an int or a double.

class Detail
{
public int UnitCount;
public double UnitPrice;
...
}

void ComputeSums() {
ItemList<Detail> orderDetails = GetOrderDetails(...);
int totalUnits = orderDetails.Sum(d => d.UnitCount);
double orderTotal = orderDetails.Sum(d => d.UnitPrice * d.UnitCount);
...
}


### 外部變數Outer variables

#### 已捕捉的外部變數Captured outer variables

using System;

delegate int D();

class Test
{
static D F() {
int x = 0;
D result = () => ++x;
return result;
}

static void Main() {
D d = F();
Console.WriteLine(d());
Console.WriteLine(d());
Console.WriteLine(d());
}
}


1
2
3


#### 區域變數的具現化Instantiation of local variables

static void F() {
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
...
}
}


static void F() {
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
...
}
}


using System;

delegate void D();

class Test
{
static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}

static void Main() {
foreach (D d in F()) d();
}
}


1
3
5


static D[] F() {
D[] result = new D[3];
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}


5
5
5


static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
result[i] = () => { Console.WriteLine(i); };
}
return result;
}


3
3
3


static D[] F() {
D[] result = new D[3];
int x = 0;
for (int i = 0; i < 3; i++) {
int y = 0;
result[i] = () => { Console.WriteLine("{0} {1}", ++x, ++y); };
}
return result;
}


1 1
2 1
3 1


using System;

delegate void Setter(int value);

delegate int Getter();

class Test
{
static void Main() {
int x = 0;
Setter s = (int value) => { x = value; };
Getter g = () => { return x; };
s(5);
Console.WriteLine(g());
s(10);
Console.WriteLine(g());
}
}


5
10


## 查詢運算式Query expressions

query_expression
: from_clause query_body
;

from_clause
: 'from' type? identifier 'in' expression
;

query_body
: query_body_clauses? select_or_group_clause query_continuation?
;

query_body_clauses
: query_body_clause
| query_body_clauses query_body_clause
;

query_body_clause
: from_clause
| let_clause
| where_clause
| join_clause
| join_into_clause
| orderby_clause
;

let_clause
: 'let' identifier '=' expression
;

where_clause
: 'where' boolean_expression
;

join_clause
: 'join' type? identifier 'in' expression 'on' expression 'equals' expression
;

join_into_clause
: 'join' type? identifier 'in' expression 'on' expression 'equals' expression 'into' identifier
;

orderby_clause
: 'orderby' orderings
;

orderings
: ordering (',' ordering)*
;

ordering
: expression ordering_direction?
;

ordering_direction
: 'ascending'
| 'descending'
;

select_or_group_clause
: select_clause
| group_clause
;

select_clause
: 'select' expression
;

group_clause
: 'group' expression 'by' expression
;

query_continuation
: 'into' identifier query_body
;


### 查詢運算式轉譯Query expression translation

C # 語言不會指定查詢運算式的執行語法。The C# language does not specify the execution semantics of query expressions. 相反地，查詢運算式會轉譯成符合 查詢運算式模式 的方法調用， (查詢運算式模式) 。Rather, query expressions are translated into invocations of methods that adhere to the query expression pattern (The query expression pattern). 具體而言，查詢運算式會轉譯為名為 Where 、、 Select SelectManyJoinGroupJoin OrderBy OrderByDescending ThenBy ThenByDescending GroupBy Cast 、、、、、和的方法調用。這些方法預期會有特定的簽章和結果類型，如 查詢運算式模式中所述。Specifically, query expressions are translated into invocations of methods named Where, Select, SelectMany, Join, GroupJoin, OrderBy, OrderByDescending, ThenBy, ThenByDescending, GroupBy, and Cast.These methods are expected to have particular signatures and result types, as described in The query expression pattern. 這些方法可以是所查詢之物件的實例方法或物件外部的擴充方法，而且它們會執行查詢的實際執行。These methods can be instance methods of the object being queried or extension methods that are external to the object, and they implement the actual execution of the query.

#### 具有接續的 Select 和 groupby 子句Select and groupby clauses with continuations

from ... into x ...


from x in ( from ... ) ...


from c in customers
group c by c.Country into g
select new { Country = g.Key, CustCount = g.Count() }


from g in
from c in customers
group c by c.Country
select new { Country = g.Key, CustCount = g.Count() }


customers.
GroupBy(c => c.Country).
Select(g => new { Country = g.Key, CustCount = g.Count() })


#### 明確範圍變數類型Explicit range variable types

from明確指定範圍變數類型的子句。A from clause that explicitly specifies a range variable type

from T x in e


from x in ( e ) . Cast < T > ( )


join明確指定範圍變數類型的子句。A join clause that explicitly specifies a range variable type

join T x in e on k1 equals k2


join x in ( e ) . Cast < T > ( ) on k1 equals k2


from Customer c in customers
where c.City == "London"
select c


from c in customers.Cast<Customer>()
where c.City == "London"
select c


customers.
Cast<Customer>().
Where(c => c.City == "London")


#### 退化查詢運算式Degenerate query expressions

from x in e select x


( e ) . Select ( x => x )


from c in customers
select c


customers.Select(c => c)


#### From、let、where、join 和 orderby 子句From, let, where, join and orderby clauses

from x1 in e1
from x2 in e2
select v


( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )


from x1 in e1
from x2 in e2
...


from * in ( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => new { x1 , x2 } )
...


from x in e
let y = f
...


from * in ( e ) . Select ( x => new { x , y = f } )
...


from x in e
where f
...


from x in ( e ) . Where ( x => f )
...


from x1 in e1
join x2 in e2 on k1 equals k2
select v


( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => v )


from x1 in e1
join x2 in e2 on k1 equals k2
...


from * in ( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => new { x1 , x2 })
...


from x1 in e1
join x2 in e2 on k1 equals k2 into g
select v


( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => v )


from x1 in e1
join x2 in e2 on k1 equals k2 into g
...


from * in ( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => new { x1 , g })
...


from x in e
orderby k1 , k2 , ..., kn
...


from x in ( e ) .
OrderBy ( x => k1 ) .
ThenBy ( x => k2 ) .
... .
ThenBy ( x => kn )
...


from c in customers
from o in c.Orders
select new { c.Name, o.OrderID, o.Total }


customers.
SelectMany(c => c.Orders,
(c,o) => new { c.Name, o.OrderID, o.Total }
)


from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }


from * in customers.
SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.OrderID, o.Total }


customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.OrderID, x.o.Total })


from o in orders
let t = o.Details.Sum(d => d.UnitPrice * d.Quantity)
where t >= 1000
select new { o.OrderID, Total = t }


from * in orders.
Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) })
where t >= 1000
select new { o.OrderID, Total = t }


orders.
Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) }).
Where(x => x.t >= 1000).
Select(x => new { x.o.OrderID, Total = x.t })


from c in customers
join o in orders on c.CustomerID equals o.CustomerID
select new { c.Name, o.OrderDate, o.Total }


customers.Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c.Name, o.OrderDate, o.Total })


from c in customers
join o in orders on c.CustomerID equals o.CustomerID into co
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }


from * in customers.
GroupJoin(orders, c => c.CustomerID, o => o.CustomerID,
(c, co) => new { c, co })
let n = co.Count()
where n >= 10
select new { c.Name, OrderCount = n }


customers.
GroupJoin(orders, c => c.CustomerID, o => o.CustomerID,
(c, co) => new { c, co }).
Select(x => new { x, n = x.co.Count() }).
Where(y => y.n >= 10).
Select(y => new { y.x.c.Name, OrderCount = y.n)


from o in orders
orderby o.Customer.Name, o.Total descending
select o


orders.
OrderBy(o => o.Customer.Name).
ThenByDescending(o => o.Total)


#### Select 子句Select clauses

from x in e select v


( e ) . Select ( x => v )


( e )


from c in customers.Where(c => c.City == "London")
select c


customers.Where(c => c.City == "London")


#### Groupby 子句Groupby clauses

from x in e group v by k


( e ) . GroupBy ( x => k , x => v )


( e ) . GroupBy ( x => k )


from c in customers
group c.Name by c.Country


customers.
GroupBy(c => c.Country, c => c.Name)


#### 透明識別碼Transparent identifiers

• 當透明識別碼以匿名函式中的參數形式出現時，關聯匿名型別的成員會自動在匿名函數主體的範圍內。When a transparent identifier occurs as a parameter in an anonymous function, the members of the associated anonymous type are automatically in scope in the body of the anonymous function.
• 當具有透明識別碼的成員在範圍內時，該成員的成員也會在範圍中。When a member with a transparent identifier is in scope, the members of that member are in scope as well.
• 當透明識別碼以匿名物件初始化運算式中的成員宣告子形式出現時，會引入具有透明識別碼的成員。When a transparent identifier occurs as a member declarator in an anonymous object initializer, it introduces a member with a transparent identifier.
• 在上述的轉譯步驟中，透明的識別碼一律會與匿名型別一起導入，而意圖是將多個範圍變數當作單一物件的成員來捕捉。In the translation steps described above, transparent identifiers are always introduced together with anonymous types, with the intent of capturing multiple range variables as members of a single object. C # 的執行允許使用與匿名型別不同的機制，將多個範圍變數群組在一起。An implementation of C# is permitted to use a different mechanism than anonymous types to group together multiple range variables. 下列轉譯範例假設使用匿名型別，並顯示透明識別碼如何轉譯。The following translation examples assume that anonymous types are used, and show how transparent identifiers can be translated away.

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.Total }


from * in customers.
SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.Total }


customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(* => o.Total).
Select(* => new { c.Name, o.Total })


customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.Total })


from c in customers
join o in orders on c.CustomerID equals o.CustomerID
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }


from * in customers.
Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c, o })
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }


customers.
Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c, o }).
Join(details, * => o.OrderID, d => d.OrderID, (*, d) => new { *, d }).
Join(products, * => d.ProductID, p => p.ProductID, (*, p) => new { *, p }).
Select(* => new { c.Name, o.OrderDate, p.ProductName })


customers.
Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c, o }).
Join(details, x => x.o.OrderID, d => d.OrderID,
(x, d) => new { x, d }).
Join(products, y => y.d.ProductID, p => p.ProductID,
(y, p) => new { y, p }).
Select(z => new { z.y.x.c.Name, z.y.x.o.OrderDate, z.p.ProductName })


### 查詢運算式模式The query expression pattern

delegate R Func<T1,R>(T1 arg1);

delegate R Func<T1,T2,R>(T1 arg1, T2 arg2);

class C
{
public C<T> Cast<T>();
}

class C<T> : C
{
public C<T> Where(Func<T,bool> predicate);

public C<U> Select<U>(Func<T,U> selector);

public C<V> SelectMany<U,V>(Func<T,C<U>> selector,
Func<T,U,V> resultSelector);

public C<V> Join<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
Func<U,K> innerKeySelector, Func<T,U,V> resultSelector);

public C<V> GroupJoin<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
Func<U,K> innerKeySelector, Func<T,C<U>,V> resultSelector);

public O<T> OrderBy<K>(Func<T,K> keySelector);

public O<T> OrderByDescending<K>(Func<T,K> keySelector);

public C<G<K,T>> GroupBy<K>(Func<T,K> keySelector);

public C<G<K,E>> GroupBy<K,E>(Func<T,K> keySelector,
Func<T,E> elementSelector);
}

class O<T> : C<T>
{
public O<T> ThenBy<K>(Func<T,K> keySelector);

public O<T> ThenByDescending<K>(Func<T,K> keySelector);
}

class G<K,T> : C<T>
{
public K Key { get; }
}


System.Linq命名空間會為實介面的任何型別提供查詢運算子模式的實作為 System.Collections.Generic.IEnumerable<T>The System.Linq namespace provides an implementation of the query operator pattern for any type that implements the System.Collections.Generic.IEnumerable<T> interface.

## 指派運算子Assignment operators

assignment
: unary_expression assignment_operator expression
;

assignment_operator
: '='
| '+='
| '-='
| '*='
| '/='
| '%='
| '&='
| '|='
| '^='
| '<<='
| right_shift_assignment
;


=運算子稱為 簡單指派運算子The = operator is called the simple assignment operator. 它會將右運算元的值指派給左運算元所指定的變數、屬性或索引子元素。It assigns the value of the right operand to the variable, property, or indexer element given by the left operand. 簡單指派運算子的左運算元可能不是事件存取 (但如 類似欄位的事件) 中所述。The left operand of the simple assignment operator may not be an event access (except as described in Field-like events). 簡單指派運算子會在 簡單指派中描述。The simple assignment operator is described in Simple assignment.

+= -= 使用事件存取運算式作為左運算元的和運算子，稱為 事件指派運算子The += and -= operators with an event access expression as the left operand are called the event assignment operators. 沒有其他指派運算子適用于以事件存取作為左運算元。No other assignment operator is valid with an event access as the left operand. 事件指派運算子會在 事件指派中描述。The event assignment operators are described in Event assignment.

### 單一指派Simple assignment

=運算子稱為簡單指派運算子。The = operator is called the simple assignment operator.

• 如果 x 分類為變數：If x is classified as a variable:
• x 會評估以產生變數。x is evaluated to produce the variable.
• y 會進行評估，並視需要透過隱含轉換轉換成的類型 x (隱含 轉換) 。y is evaluated and, if required, converted to the type of x through an implicit conversion (Implicit conversions).
• 如果所指定的變數 xreference_type 的陣列元素，則會執行執行時間檢查，以確保計算的值 y 與的陣列實例相容，其 x 為元素。If the variable given by x is an array element of a reference_type, a run-time check is performed to ensure that the value computed for y is compatible with the array instance of which x is an element. 如果 ynull ，或如果隱含參考轉換 (隱含參考 轉換) 存在於所參考之 y 陣列實例的實際元素類型中，則檢查會成功 xThe check succeeds if y is null, or if an implicit reference conversion (Implicit reference conversions) exists from the actual type of the instance referenced by y to the actual element type of the array instance containing x. 否則會擲回 System.ArrayTypeMismatchExceptionOtherwise, a System.ArrayTypeMismatchException is thrown.
• 評估和轉換所產生的值 y 會儲存至評估所指定的位置 xThe value resulting from the evaluation and conversion of y is stored into the location given by the evaluation of x.
• 如果 x 分類為屬性或索引子存取：If x is classified as a property or indexer access:
• 如果不是) ，則為實例運算式 (如果 x static 是，則為引數清單 (如果 x 是，則會評估與相關聯的索引子存取) x ，而且結果會用於後續的 set 存取子調用。The instance expression (if x is not static) and the argument list (if x is an indexer access) associated with x are evaluated, and the results are used in the subsequent set accessor invocation.
• y 會進行評估，並視需要透過隱含轉換轉換成的類型 x (隱含 轉換) 。y is evaluated and, if required, converted to the type of x through an implicit conversion (Implicit conversions).
• set 存取子 x 會以計算的值 y 做為其引數來叫用 valueThe set accessor of x is invoked with the value computed for y as its value argument.

string[] sa = new string[10];
object[] oa = sa;

oa[0] = null;               // Ok
oa[1] = "Hello";            // Ok
oa[2] = new ArrayList();    // ArrayTypeMismatchException


struct_type 中宣告的屬性或索引子是指派的目標時，與屬性或索引子存取相關聯的實例運算式必須分類為變數。When a property or indexer declared in a struct_type is the target of an assignment, the instance expression associated with the property or indexer access must be classified as a variable. 如果實例運算式分類為值，就會發生系結階段錯誤。If the instance expression is classified as a value, a binding-time error occurs. 由於 成員存取，相同的規則也適用于欄位。Because of Member access, the same rule also applies to fields.

struct Point
{
int x, y;

public Point(int x, int y) {
this.x = x;
this.y = y;
}

public int X {
get { return x; }
set { x = value; }
}

public int Y {
get { return y; }
set { y = value; }
}
}

struct Rectangle
{
Point a, b;

public Rectangle(Point a, Point b) {
this.a = a;
this.b = b;
}

public Point A {
get { return a; }
set { a = value; }
}

public Point B {
get { return b; }
set { b = value; }
}
}


Point p = new Point();
p.X = 100;
p.Y = 100;
Rectangle r = new Rectangle();
r.A = new Point(10, 10);
r.B = p;


p.X p.Y r.A r.B 由於 pr 都是變數，因此允許指派給、、和。the assignments to p.X, p.Y, r.A, and r.B are permitted because p and r are variables. 不過，在範例中However, in the example

Rectangle r = new Rectangle();
r.A.X = 10;
r.A.Y = 10;
r.B.X = 100;
r.B.Y = 100;


### 複合指派Compound assignment

x op= y 由套用二元運算子多載解析 (二元運算子 多載解析) 和寫入作業的方式來處理表單的作業 x op yAn operation of the form x op= y is processed by applying binary operator overload resolution (Binary operator overload resolution) as if the operation was written x op y. 如此一來，Then,

• 如果所選運算子的傳回型別可隱含轉換成的型別 x ，則作業會評估為 x = x op y ，但是 x 只會評估一次。If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as x = x op y, except that x is evaluated only once.
• 否則，如果選取的運算子是預先定義的運算子，則如果所選運算子的傳回型別明確地轉換成的型別 x ，而且如果 y 可以隱含地轉換成的型別 x 或運算子是移位運算子，則作業會評估為 x = (T)(x op y) ，其中 T 是的型別， x 但是 x 只會評估一次。Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once.
• 否則，複合指派是不正確，而且會發生系結階段錯誤。Otherwise, the compound assignment is invalid, and a binding-time error occurs.

「只評估一次」一詞表示在的評估中 x op y ，會暫時儲存任何組成運算式的結果， x 然後在執行指派給時重複使用 xThe term "evaluated only once" means that in the evaluation of x op y, the results of any constituent expressions of x are temporarily saved and then reused when performing the assignment to x. 例如，在指派中 A()[B()] += C() ，其中是傳回的 A 方法 int[] ，且 B 和都是傳回的 C 方法 int ，則只會叫用一次方法，順序為 A B CFor example, in the assignment A()[B()] += C(), where A is a method returning int[], and B and C are methods returning int, the methods are invoked only once, in the order A, B, C.

byte b = 0;
char ch = '\0';
int i = 0;

b += 1;             // Ok
b += 1000;          // Error, b = 1000 not permitted
b += i;             // Error, b = i not permitted
b += (byte)i;       // Ok

ch += 1;            // Error, ch = 1 not permitted
ch += (char)1;      // Ok


int? i = 0;
i += 1;             // Ok


### 事件指派Event assignment

• 評估事件存取的實例運算式（如果有的話）。The instance expression, if any, of the event access is evaluated.
• += -= 系統會評估 or 運算子的右運算元，並在必要時，透過隱含轉換 (隱含轉換) 來轉換成左運算元的類型。The right operand of the += or -= operator is evaluated, and, if required, converted to the type of the left operand through an implicit conversion (Implicit conversions).
• 系統會叫用事件的事件存取子，並在評估之後、以及（如有必要）轉換之後，使用由右運算元組成的引數清單。An event accessor of the event is invoked, with argument list consisting of the right operand, after evaluation and, if necessary, conversion. 如果運算子是，則會叫用 += add 存取子; 如果運算子是 -= ，則 remove 會叫用存取子。If the operator was +=, the add accessor is invoked; if the operator was -=, the remove accessor is invoked.

## 運算式Expression

expression
: non_assignment_expression
| assignment
;

non_assignment_expression
: conditional_expression
| lambda_expression
| query_expression
;


## 常數運算式Constant expressions

Constant_expression 是可在編譯時期完整評估的運算式。A constant_expression is an expression that can be fully evaluated at compile-time.

constant_expression
: expression
;


• 常值 (包括 null 常值) 。Literals (including the null literal).
• const類別和結構類型成員的參考。References to const members of class and struct types.
• 列舉類型成員的參考。References to members of enumeration types.
• const參數或本機變數的參考References to const parameters or local variables
• 括弧內的子運算式，也就是常數運算式。Parenthesized sub-expressions, which are themselves constant expressions.
• Cast 運算式（如果目標型別是以上所列的其中一種類型的話）。Cast expressions, provided the target type is one of the types listed above.
• checkedunchecked 運算式checked and unchecked expressions
• 預設值運算式Default value expressions
• Nameof 運算式Nameof expressions
• 預先定義的 + 、、 - !~ 一元運算子。The predefined +, -, !, and ~ unary operators.
• 預先定義的、、、、、、、、、、、、、、、、 + - * / % << >> & | ^ && || == != < > <=>= 二元運算子，提供的每個運算元都是上述類型。The predefined +, -, *, /, %, <<, >>, &, |, ^, &&, ||, ==, !=, <, >, <=, and >= binary operators, provided each operand is of a type listed above.
• ?:條件運算子。The ?: conditional operator.

• 身分識別轉換Identity conversions
• 數值轉換Numeric conversions
• 列舉轉換Enumeration conversions
• 常數運算式轉換Constant expression conversions
• 隱含和明確的參考轉換，前提是轉換的來源是評估為 null 值的常數運算式。Implicit and explicit reference conversions, provided that the source of the conversions is a constant expression that evaluates to the null value.

class C {
const object i = 5;         // error: boxing conversion not permitted
const object str = "hello"; // error: implicit reference conversion
}


## 布林運算式Boolean expressions

Boolean_expression 是在特定內容中直接或透過應用程式產生型別結果的運算式， bool operator true 如下列所指定。A boolean_expression is an expression that yields a result of type bool; either directly or through application of operator true in certain contexts as specified in the following.

boolean_expression
: expression
;


If_statement (if 語句的控制條件運算式) 、 while_statement (while 語句 ) 、do_statement ( do 語句) ，或 for_statement (for 語句) 是 boolean_expressionThe controlling conditional expression of an if_statement (The if statement), while_statement (The while statement), do_statement (The do statement), or for_statement (The for statement) is a boolean_expression. 運算子的控制條件運算式 ?: (條件運算子) 遵循與 boolean_expression 相同的規則，但基於運算子優先順序的原因，會分類為 conditional_or_expressionThe controlling conditional expression of the ?: operator (Conditional operator) follows the same rules as a boolean_expression, but for reasons of operator precedence is classified as a conditional_or_expression.

• 如果在 E bool 執行時間可隱含轉換為，則會套用隱含轉換。If E is implicitly convertible to bool then at runtime that implicit conversion is applied.
• 否則，一元運算子多載解析 (一元運算子 多載解析) 用來在上尋找運算子的唯一最佳實作為 true E ，並在執行時間套用該實作為。Otherwise, unary operator overload resolution (Unary operator overload resolution) is used to find a unique best implementation of operator true on E, and that implementation is applied at runtime.
• 如果找不到這類運算子，就會發生系結階段錯誤。If no such operator is found, a binding-time error occurs.

DBBool資料庫布林值型別中的結構類型提供實和的型別 operator true 範例 operator falseThe DBBool struct type in Database boolean type provides an example of a type that implements operator true and operator false.