指派運算子 = 會將其右方運算元的值指派給其左方運算元所指定的變數、屬性或索引子元素。 指派運算式的結果是指派給左方運算元的值。 右方運算元的型別必須與左方運算元的型別相同,或是會隱含地轉換成該型別。
指派運算子 = 是右向關聯運算子,亦即,以下形式的運算式
a = b = c
評估為
a = (b = c)
下列範例示範將區域變數、屬性及索引子元素作為指派運算子左運算元的用法:
List<double> numbers = [1.0, 2.0, 3.0];
Console.WriteLine(numbers.Capacity);
numbers.Capacity = 100;
Console.WriteLine(numbers.Capacity);
// Output:
// 4
// 100
int newFirstElement;
double originalFirstElement = numbers[0];
newFirstElement = 5;
numbers[0] = newFirstElement;
Console.WriteLine(originalFirstElement);
Console.WriteLine(numbers[0]);
// Output:
// 1
// 5
指派的左側運算元會接收右側運算元的值。 當運算元屬於實值型別時,指派會複製右側運算元的內容。 當運算元屬於參考型別時,指派會將參考複製到該物件。
這項作業稱為 賦值:這是將值進行賦予的過程。
從 C# 14 開始,值指派的左側可以包含 Null 條件式成員表示式,例如 ?. 或 ?[]。 如果左側為 Null,則不會評估右側表達式。
ref 指派
Ref 指派= ref會讓其左側運算元成為右側運算元的別名,如下列範例所示:
void Display(double[] s) => Console.WriteLine(string.Join(" ", s));
double[] arr = { 0.0, 0.0, 0.0 };
Display(arr);
ref double arrayElement = ref arr[0];
arrayElement = 3.0;
Display(arr);
arrayElement = ref arr[arr.Length - 1];
arrayElement = 5.0;
Display(arr);
// Output:
// 0 0 0
// 3 0 0
// 3 0 5
在上述範例中,本機參考變數arrayElement會初始化為第一個陣列元素的別名。 然後它會 ref 重新指派以參考最後一個陣列元素。 由於是別名,因此當您使用一般指派運算子 = 更新其值時,對應的陣列元素也會更新。
ref 指派的左側運算元可以是本機參考變數、ref 欄位,以及 ref、out 或 in 方法參數。 兩個運算元的類型必須相同。
ref指派代表參考變數有不同的指稱對象。 它不再指的是之前的指稱。 在 ref = 參數上使用 ref 表示參數不再參考其自變數。 在 ref 重新指派對象之後修改物件狀態的任何動作,都對新項目進行這些修改。 例如,請考慮下列方法:
private static void RefReassignAndModify(scoped ref string s)
{
string sLocal = "Hello";
Console.WriteLine(sLocal); // Output: Hello
s = ref sLocal;
s = "World";
Console.WriteLine(s); // Output: World
下列用法顯示,在方法呼叫之後看不到參數 s 指派,因為 sref 重新指派以在修改字串之前參考 sLocal:
string msg = "Hi";
RefReassignAndModify(ref msg);
Console.WriteLine(msg); // Output: Hi
複合指派
若是二元運算子 op,表單的複合指派運算式
x op= y
相當於
x = x op y
不同之處在於 x 只會評估一次。
Null 聯合指派
只有當左側運算元評估為 ??= 時,才能使用 Null 聯合指派運算子 null 將右側運算元的值指派給左側運算元。 如需詳細資訊,請參閱 ?? 和 ??= 運算元 一文。
運算子是否可多載
使用者定義型別無法多載指派運算子。 不過,使用者定義型別可以定義會轉換成另一型別的隱含轉換。 如此一來,便可將使用者定義型別的值指派給另一型別的變數、屬性或索引子元素。 如需詳細資訊,請參閱使用者定義轉換運算子。
如果使用者定義型別多載二進位運算元op,那麼如果運算子op=存在,則也會隱含多載。 從 C# 14 開始,使用者定義型別可以明確多載複合指派運算子 (op=) 以提供更有效率的實作。 一般而言,型別會多載這些運算符,因為值可以就地更新,而不是配置新的實例來保存二進位作業的結果。 如果類型未提供明確的多載,編譯程式會產生隱含多載。
C# 語言規格
如需詳細資訊,請參閱 C# 語言規格的指派運算符一節和使用者定義的複合指派功能規格。