C# zachowuje się tak samo, z tym że w C# nie da się zrobić tego przypadkiem. Żeby użyć "widoku" na wycinek listy trzeba użyć CollectionsMarshal.AsSpan a ten ma uwagę że Items should not be added or removed from the List<T> while the Span<T> is in use..
Kopiuj
using System.Runtime.InteropServices;
int foo(int capacity)
{
List<int> x = new(capacity);
x.AddRange([1, 2, 3, 4]);
var y = CollectionsMarshal.AsSpan(x)[1..3];
Console.WriteLine($"Before modification. Capacity: {capacity}");
Console.WriteLine($"x: [{string.Join(" ", x)}]");
Console.WriteLine($"y: [{string.Join(" ", y.ToArray())}]");
x.AddRange([11, 12]);
y[1] = -1;
Console.WriteLine($"After modification. Capacity: {capacity}");
Console.WriteLine($"x: [{string.Join(" ", x)}]");
Console.WriteLine($"y: [{string.Join(" ", y.ToArray())}]");
return x[2];
}
var a = foo(5);
var b = foo(6);
Console.WriteLine($"a: {a} b: {b}");
wynik taki sam:
Kopiuj
Before modification. Capacity: 5
x: [1 2 3 4]
y: [2 3]
After modification. Capacity: 5
x: [1 2 3 4 11 12]
y: [2 -1]
Before modification. Capacity: 6
x: [1 2 3 4]
y: [2 3]
After modification. Capacity: 6
x: [1 2 -1 4 11 12]
y: [2 -1]
a: 3 b: -1
Powód taki jak napisano w komentarzach powyżej - przy przekroczeniu pojemności listy, tworzona jest pod spodem nowa, większa tablica a mamy referencję na starą tablicę.
W zasadzie go też tu pokazuje że mutujesz x
Kopiuj
x = append(x, 11, 12)
więc nie powinno nic dziwić; wszystko jest logiczne bo zamiana tego na
Kopiuj
z := append(x, 11, 12)
y[1] = -1
fmt.Println("After modification. Capacity: ", capacity)
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("z:", z)
pokazuje
Kopiuj
Before modification. Capacity: 5
x: [1 2 3 4]
y: [2 3]
After modification. Capacity: 5
x: [1 2 -1 4]
y: [2 -1]
z: [1 2 3 4 11 12]
Before modification. Capacity: 6
x: [1 2 3 4]
y: [2 3]
After modification. Capacity: 6
x: [1 2 -1 4]
y: [2 -1]
z: [1 2 -1 4 11 12]
a: -1 b: -1
Choć tu z kolei zaskakujące jest że przy capacity 6 zmienione zostało zarówno x jak i z co świadczy że x jest tą samą tablicą co z a jednak przy wyświetlaniu elementów x pokazuje tylko 4 elementy a z 6. Ciekawy język