成員訪問運算子和運算式(C# 引用)Member access operators and expressions (C# reference)

訪問類型成員時,可以使用以下運算子和運算式:You can use the following operators and expressions when you access a type member:

成員訪問運算式 .Member access expression .

您會使用 . 語彙基元來存取命名空間或類型的成員,如下列範例所示:You use the . token to access a member of a namespace or a type, as the following examples demonstrate:

  • 用於.訪問命名空間中的嵌套命名空間,如以下using指令示例所示:Use . to access a nested namespace within a namespace, as the following example of a using directive shows:

    using System.Collections.Generic;
    
  • 使用 . 來形成「限定名稱」** 以存取命名空間內的類型,如下列程式碼所示:Use . to form a qualified name to access a type within a namespace, as the following code shows:

    System.Collections.Generic.IEnumerable<int> numbers = new int[] { 1, 2, 3 };
    

    使用using指令使限定名稱的使用成為可選名稱。Use a using directive to make the use of qualified names optional.

  • 使用 . 來存取類型成員 (靜態及非靜態),如下列程式碼所示:Use . to access type members, static and non-static, as the following code shows:

    var constants = new List<double>();
    constants.Add(Math.PI);
    constants.Add(Math.E);
    Console.WriteLine($"{constants.Count} values to show:");
    Console.WriteLine(string.Join(", ", constants));
    // Output:
    // 2 values to show:
    // 3.14159265358979, 2.71828182845905
    

您也可以使用 . 來存取擴充方法You can also use . to access an extension method.

索引子運算子 []Indexer operator []

中括弧 ([]) 通常用於陣列、索引子或指標元素存取。Square brackets, [], are typically used for array, indexer, or pointer element access.

陣列存取Array access

以下範例將示範如何存取陣列元素:The following example demonstrates how to access array elements:

int[] fib = new int[10];
fib[0] = fib[1] = 1;
for (int i = 2; i < fib.Length; i++)
{
    fib[i] = fib[i - 1] + fib[i - 2];
}
Console.WriteLine(fib[fib.Length - 1]);  // output: 55

double[,] matrix = new double[2,2];
matrix[0,0] = 1.0;
matrix[0,1] = 2.0;
matrix[1,0] = matrix[1,1] = 3.0;
var determinant = matrix[0,0] * matrix[1,1] - matrix[1,0] * matrix[0,1];
Console.WriteLine(determinant);  // output: -3

如果陣列索引超出陣列的對應維度界限,就會擲回 IndexOutOfRangeExceptionIf an array index is outside the bounds of the corresponding dimension of an array, an IndexOutOfRangeException is thrown.

如上述範例所示,您也會在宣告陣列類型或將陣列執行個體具現化時使用方括弧。As the preceding example shows, you also use square brackets when you declare an array type or instantiate an array instance.

如需陣列的詳細資訊,請參閱陣列For more information about arrays, see Arrays.

索引子存取Indexer access

下面的示例使用 .NETDictionary<TKey,TValue>類型來演示索引子訪問:The following example uses the .NET Dictionary<TKey,TValue> type to demonstrate indexer access:

var dict = new Dictionary<string, double>();
dict["one"] = 1;
dict["pi"] = Math.PI;
Console.WriteLine(dict["one"] + dict["pi"]);  // output: 4.14159265358979

索引子可讓您透過與陣列編製索引類似的方式,為使用者定義型別的執行個體編製索引。Indexers allow you to index instances of a user-defined type in the similar way as array indexing. 與陣列索引(必須整數)不同,索引子參數可以聲明為任何類型的索引子參數。Unlike array indices, which must be integer, the indexer parameters can be declared to be of any type.

如需索引子的詳細資訊,請參閱索引子For more information about indexers, see Indexers.

[] 的其他用法Other usages of []

如需有關指標元素存取的相關資訊,請參閱指標相關運算子一文的指標元素存取運算子 [] 一節。For information about pointer element access, see the Pointer element access operator [] section of the Pointer related operators article.

您也可以使用中括弧來指定屬性You also use square brackets to specify attributes:

[System.Diagnostics.Conditional("DEBUG")]
void TraceMethod() {}

Null 條件運算子 ?.Null-conditional operators ?. 和 ?[]and ?[]

在 C# 6 和更高版本中可用,null 條件運算子僅當該?.運算元計算為非?[]null 時,才會將成員訪問、或元素訪問操作應用於其運算元;否則,它將返回nullAvailable in C# 6 and later, a null-conditional operator applies a member access, ?., or element access, ?[], operation to its operand only if that operand evaluates to non-null; otherwise, it returns null. 那是That is,

  • 如果a計算 到nulla?.x的結果a?[x]nullIf a evaluates to null, the result of a?.x or a?[x] is null.

  • 如果a計算為a?.x非空,則 或a?[x]的結果與a.xa[x]的結果相同。If a evaluates to non-null, the result of a?.x or a?[x] is the same as the result of a.x or a[x], respectively.

    注意

    如果a.xa[x]引發異常,a?.xa?[x]將為非 nulla引發相同的異常。If a.x or a[x] throws an exception, a?.x or a?[x] would throw the same exception for non-null a. 例如,a如果是非空陣列實例,並且x超出 的邊界aa?[x]則將引發 。 IndexOutOfRangeExceptionFor example, if a is a non-null array instance and x is outside the bounds of a, a?[x] would throw an IndexOutOfRangeException.

Null 條件運算子會執行最少運算。The null-conditional operators are short-circuiting. 換句話說,如果條件式成員或項目存取作業鏈結中的一個作業傳回 null,則鏈結的其餘部分不會執行。That is, if one operation in a chain of conditional member or element access operations returns null, the rest of the chain doesn't execute. 在下列範例中,如果 A 評估為 null,則不會評估 B;如果 AB 評估為 null,則不會評估 CIn the following example, B is not evaluated if A evaluates to null and C is not evaluated if A or B evaluates to null:

A?.B?.Do(C);
A?.B?[C];

下列範例示範 ?.?[] 運算子的用法:The following example demonstrates the usage of the ?. and ?[] operators:

double SumNumbers(List<double[]> setsOfNumbers, int indexOfSetToSum)
{
    return setsOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
}

var sum1 = SumNumbers(null, 0);
Console.WriteLine(sum1);  // output: NaN

var numberSets = new List<double[]>
{
    new[] { 1.0, 2.0, 3.0 },
    null
};

var sum2 = SumNumbers(numberSets, 0);
Console.WriteLine(sum2);  // output: 6

var sum3 = SumNumbers(numberSets, 1);
Console.WriteLine(sum3);  // output: NaN

前面的示例還使用null 合併運算子??指定一個替代運算式,以計算 null 條件操作的結果為null時計算的運算式。The preceding example also uses the null-coalescing operator ?? to specify an alternative expression to evaluate in case the result of a null-conditional operation is null.

Null 條件成員存取運算子 ?. 也被稱為 Elvis 運算子。The null-conditional member access operator ?. is also known as the Elvis operator.

安全執行緒委派引動流程Thread-safe delegate invocation

使用 ?. 運算子來檢查委派是否為非 Null,然後以安全執行緒方式叫用它 (例如當您引發事件時),如下列程式碼所示:Use the ?. operator to check if a delegate is non-null and invoke it in a thread-safe way (for example, when you raise an event), as the following code shows:

PropertyChanged?.Invoke(…)

該程式碼等同於您用於 C# 5 或舊版的下列程式碼:That code is equivalent to the following code that you would use in C# 5 or earlier:

var handler = this.PropertyChanged;
if (handler != null)
{
    handler(…);
}

調用運算式 ()Invocation expression ()

使用括弧 () 來呼叫方法或叫用委派Use parentheses, (), to call a method or invoke a delegate.

下列範例示範如何呼叫方法 (使用或不使用引數),以及叫用委派:The following example demonstrates how to call a method, with or without arguments, and invoke a delegate:

Action<int> display = s => Console.WriteLine(s);

var numbers = new List<int>();
numbers.Add(10);
numbers.Add(17);
display(numbers.Count);   // output: 2

numbers.Clear();
display(numbers.Count);   // output: 0

當您使用 new 運算子叫用建構函式時,您也會使用括號。You also use parentheses when you invoke a constructor with the new operator.

() 的其他用法Other usages of ()

您也可以使用括弧來調整評估運算式中作業的順序。You also use parentheses to adjust the order in which to evaluate operations in an expression. 如需詳細資訊,請參閱 C# 運算子For more information, see C# operators.

Cast 運算式 (其能執行明確類型轉換) 也會使用括號。Cast expressions, which perform explicit type conversions, also use parentheses.

來自終端運算子的索引 |Index from end operator ^

在 C# 8.0 及更高^版本中可用,運算子指示序列末尾的元素位置。Available in C# 8.0 and later, the ^ operator indicates the element position from the end of a sequence. 對於長度length序列,^n指向具有序列開頭偏移length - n的元素。For a sequence of length length, ^n points to the element with offset length - n from the start of a sequence. 例如,^1指向序列的最後一個元素,並^length指向序列的第一個元素。For example, ^1 points to the last element of a sequence and ^length points to the first element of a sequence.

int[] xs = new[] { 0, 10, 20, 30, 40 };
int last = xs[^1];
Console.WriteLine(last);  // output: 40

var lines = new List<string> { "one", "two", "three", "four" };
string prelast = lines[^2];
Console.WriteLine(prelast);  // output: three

string word = "Twenty";
Index toFirst = ^word.Length;
char first = word[toFirst];
Console.WriteLine(first);  // output: T

如前面的示例所示,運算式^e是類型。 System.IndexAs the preceding example shows, expression ^e is of the System.Index type. 在運算式^e中,必須將e的結果隱式轉換為intIn expression ^e, the result of e must be implicitly convertible to int.

您還可以使用運算子^範圍運算子一起創建一系列索引。You also can use the ^ operator with the range operator to create a range of indices. 有關詳細資訊,請參閱索引和範圍For more information, see Indices and ranges.

範圍運算子 ..Range operator ..

在 C# 8.0 及更高..版本中提供,運算子指定一系列索引的開始和結束作為其運算元。Available in C# 8.0 and later, the .. operator specifies the start and end of a range of indices as its operands. 左側運算元是範圍的包容性開始。The left-hand operand is an inclusive start of a range. 右側運算元是範圍的獨佔端。The right-hand operand is an exclusive end of a range. 其中任一運算元可以是序列開頭或末尾的索引,如下例所示:Either of operands can be an index from the start or from the end of a sequence, as the following example shows:

int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };
int start = 1;
int amountToTake = 3;
int[] subset = numbers[start..(start + amountToTake)];
Display(subset);  // output: 10 20 30

int margin = 1;
int[] inner = numbers[margin..^margin];
Display(inner);  // output: 10 20 30 40

string line = "one two three";
int amountToTakeFromEnd = 5;
Range endIndices = ^amountToTakeFromEnd..^0;
string end = line[endIndices];
Console.WriteLine(end);  // output: three

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

如前面的示例所示,運算式a..b是類型。 System.RangeAs the preceding example shows, expression a..b is of the System.Range type. 在運算式a..b中, 和a``b的結果必須隱式轉換為intIndex或 。In expression a..b, the results of a and b must be implicitly convertible to int or Index.

您可以省略..運算子的任何運算元以獲取開放式範圍:You can omit any of the operands of the .. operator to obtain an open-ended range:

  • a..等效于a..^0a.. is equivalent to a..^0
  • ..b等效于0..b..b is equivalent to 0..b
  • ..等效于0..^0.. is equivalent to 0..^0
int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };
int amountToDrop = numbers.Length / 2;

int[] rightHalf = numbers[amountToDrop..];
Display(rightHalf);  // output: 30 40 50

int[] leftHalf = numbers[..^amountToDrop];
Display(leftHalf);  // output: 0 10 20

int[] all = numbers[..];
Display(all);  // output: 0 10 20 30 40 50

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

有關詳細資訊,請參閱索引和範圍For more information, see Indices and ranges.

運算子是否可多載Operator overloadability

不能.()^..和 運算子。The ., (), ^, and .. operators cannot be overloaded. [] 運算子也會視為不可多載的運算子。The [] operator is also considered a non-overloadable operator. 請使用索引子以支援使用使用者定義型別編製索引。Use indexers to support indexing with user-defined types.

C# 語言規格C# language specification

如需詳細資訊,請參閱 C# 語言規格的下列幾節:For more information, see the following sections of the C# language specification:

有關索引和範圍的詳細資訊,請參閱功能建議注釋For more information about indices and ranges, see the feature proposal note.

另請參閱See also