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

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

• 用於.訪問命名空間中的嵌套命名空間，如以下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>();
Console.WriteLine(\$"{constants.Count} values to show:");
Console.WriteLine(string.Join(", ", constants));
// Output:
// 2 values to show:
// 3.14159265358979, 2.71828182845905


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

### 陣列存取Array access

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


### 索引子存取Indexer access

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


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

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


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

• 如果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];


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 條件成員存取運算子 ?. 也被稱為 Elvis 運算子。The null-conditional member access operator ?. is also known as the Elvis operator.

PropertyChanged?.Invoke(…)


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


## 調用運算式 （）Invocation expression ()

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

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

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


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

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

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

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


## 範圍運算子 ..Range operator ..

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..等效于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));