0Pricing
C# Academy · Lekcja

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]); // 5

Jawny 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,3

Wzorzec 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,30

Dlaczego 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]); // 40

Rę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]); // b

Rę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,4

Count 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]); // 4

Projektowanie 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,15

Szybkie 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 Index i Range.
  • Niejawny wzorzec: właściwość Count/Length oraz metoda Slice(int, int).
  • Metody GetOffset(Length) i GetOffsetAndLength(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

  1. Typ Index i operator ^
  2. Typ Range i operator ..
  3. Zakresy z tablicami i ciągami znaków
  4. Niestandardowe typy obsługujące zakresy
← Powrót do C# Academy