Niestandardowe typy obsługujące zakresy
Dodawaj obsługę Index i Range do własnych typów.
Niestandardowe typy obsługujące zakresy to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.
Dwa sposoby obsługi indeksów i zakresów
Własne typy mogą obsługiwać składnię Index i Range. Istnieją dwa sposoby: udostępnienie jawnych indeksatorów albo właściwości Length/Count wraz z metodą Slice.
Jawny indeksator dla Index
Należy dodać indeksator przyjmujący System.Index, a operator ^ zacznie działać z danym typem.
using System;
class Deck {
private int[] cards = { 1, 2, 3, 4, 5 };
public int this[Index i] => cards[i];
}
var d = new Deck();
Console.WriteLine(d[^1]); // 5Jawny indeksator dla Range
Aby obsługiwać wycinanie za pomocą .., należy dodać indeksator przyjmujący System.Range i zwracający wybrany typ fragmentu.
using System;
class Deck {
private int[] cards = { 1, 2, 3, 4, 5 };
public int[] this[Range r] => cards[r];
}
var d = new Deck();
Console.WriteLine(string.Join(",", d[1..3])); // 2,3Wzorzec Length + Slice
Kompilator może również automatycznie zapewnić obsługę zakresów, jeśli typ ma właściwość Count lub Length oraz metodę Slice(int start, int length).
Implementowanie wzorca
W tym przykładzie niestandardowy bufor udostępnia Length i Slice. Kompilator samodzielnie przekształca buf[1..3] w buf.Slice(1, 2).
using System;
class Buffer {
private int[] data = { 10, 20, 30, 40 };
public int Length => data.Length;
public int this[int i] => data[i];
public int[] Slice(int start, int length) {
var result = new int[length];
Array.Copy(data, start, result, 0, length);
return result;
}
}
var buf = new Buffer();
Console.WriteLine(string.Join(",", buf[1..3])); // 20,30Dlaczego Length ma znaczenie
To właściwość Length (lub Count) pozwala kompilatorowi rozwiązywać indeksy liczone od końca, takie jak ^1, dla danego typu. Bez niej operatora ^ nie można przetłumaczyć.
using System;
class Buffer {
private int[] data = { 10, 20, 30, 40 };
public int Length => data.Length;
public int this[Index i] => data[i.GetOffset(Length)];
}
var buf = new Buffer();
Console.WriteLine(buf[^1]); // 40Ręczne rozwiązywanie indeksu
W indeksatorze Index należy wywołać i.GetOffset(Length), aby przekształcić indeks, który może być liczony od końca, w zwykłe przesunięcie.
using System;
class Ring {
private string[] items = { "a", "b", "c" };
public int Length => items.Length;
public string this[Index i] {
get {
int offset = i.GetOffset(Length);
return items[offset];
}
}
}
var r = new Ring();
Console.WriteLine(r[^2]); // bRęczne rozwiązywanie zakresu
W indeksatorze Range metoda r.GetOffsetAndLength(Length) zwraca zarówno początek, jak i liczbę elementów do skopiowania.
using System;
class Ring {
private int[] items = { 1, 2, 3, 4, 5 };
public int Length => items.Length;
public int[] this[Range r] {
get {
var (start, len) = r.GetOffsetAndLength(Length);
var slice = new int[len];
Array.Copy(items, start, slice, 0, len);
return slice;
}
}
}
var r = new Ring();
Console.WriteLine(string.Join(",", r[^3..^1])); // 3,4Count a Length
Wzorzec akceptuje dowolną z tych nazw: tablice i spany używają Length, a List<T> używa Count. Każda z tych właściwości spełnia wymagania kompilatora.
using System;
using System.Collections.Generic;
var list = new List<int> { 1, 2, 3, 4 };
// List<T> has Count, so Index works:
Console.WriteLine(list[^1]); // 4Projektowanie typów zwracanych przez Slice
Należy zdecydować, czy metoda Slice zwraca kopię (jak w przypadku tablic), czy widok (jak w przypadku spanów). Widoki są tańsze, ale współdzielą zmienny stan, dlatego ten wybór należy udokumentować.
Kompletny typ niestandardowy
Typ Sequence obsługuje zarówno ^, jak i .. za pomocą jawnych indeksatorów oraz właściwości Length.
using System;
class Sequence {
private int[] data;
public Sequence(int[] d) => data = d;
public int Length => data.Length;
public int this[Index i] => data[i];
public int[] this[Range r] => data[r];
}
var s = new Sequence(new[] { 5, 10, 15, 20 });
Console.WriteLine(s[^1]); // 20
Console.WriteLine(string.Join(",", s[1..^1])); // 10,15Szybkie sprawdzenie
Należy potwierdzić, co umożliwia używanie składni zakresów w typie niestandardowym.
Podsumowanie
Dowiedzieli się Państwo o dwóch sposobach dodawania obsługi Index/Range do własnych typów.
- Jawne indeksatory przyjmujące
IndexiRange. - Niejawny wzorzec: właściwość
Count/Lengthoraz metodaSlice(int, int). - Metody
GetOffset(Length)iGetOffsetAndLength(Length)rozwiązują pozycje liczone od końca.
Często zadawane pytania
Czy lekcja „Niestandardowe typy obsługujące zakresy” jest bezpłatna?
Tak — pełny tekst „Niestandardowe typy obsługujące zakresy” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Niestandardowe typy obsługujące zakresy”?
Dodawaj obsługę Index i Range do własnych typów. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Niestandardowe typy obsługujące zakresy”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Typ Index i operator ^
- Typ Range i operator ..
- Zakresy z tablicami i ciągami znaków
- Niestandardowe typy obsługujące zakresy