天天看點

Index from end operator ^和Range operator ..

看.NET文檔發現兩個有意思的文法,一個是反向索引操作符還有一個是範圍操作符(個人翻譯)。

1:Index from end operator ^

Available in C# 8.0 and later, the ^ operator indicates the element position from the end of a sequence. For a sequence of length length, ^n points to the element with offset length - n from the start of a sequence. 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
           

As the preceding example shows, expression ^e is of the System.Index type. In expression ^e, the result of e must be implicitly convertible to int.

You can also use the ^ operator with the range operator to create a range of indices. For more information, see Indices and ranges.

之前通路List的資料,可能會寫list[list.count - 1] 現在隻需要寫list [^0] 即可。

2:Range operator …

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));
           

As the preceding example shows, expression a…b is of the System.Range type. 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.. is equivalent to a..^0
..b is equivalent to 0..b
.. 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));
           

3:備注

Indices and Ranges is a part of C# 8.0, which was released together with .NET Core 3.0 in September 2019. To use all of the C# 8.0 features, your target framework must be one of the following:

.NET Standard 2.1

.NET Core 3.0 and later

.NET 5.0 and later