Interfejsy generyczne
Uogólni Pan/Pani rozwiązania względem typów.
Interfejsy generyczne 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.
Czym jest interfejs generyczny?
Interfejs generyczny deklaruje parametry typu w nawiasach ostrych umieszczonych za nazwą. Klasy implementujące wybierają konkretne typy, a kontrakt interfejsu odpowiednio się dostosowuje.
Biblioteka .NET używa ich wszędzie, na przykład IEnumerable<T> i IComparable<T>.
interface IRepository<T>
{
void Add(T item);
T Get(int id);
}Implementowanie interfejsu generycznego
Klasa może implementować interfejs generyczny, podając konkretny argument typu. Sygnatury metod używają wtedy rzeczywistego typu.
Powstaje w ten sposób bezpieczny typowo, wielokrotnego użytku kontrakt, który nie wymaga rzutowań.
using System.Collections.Generic;
class IntStore : IRepository<int>
{
private readonly List<int> data = new();
public void Add(int item) => data.Add(item);
public int Get(int id) => data[id];
}
interface IRepository<T>
{
void Add(T item);
T Get(int id);
}Zachowanie generyczności w klasie implementującej
Klasa może implementować interfejs generyczny, pozostając jednocześnie generyczna i przekazując własny parametr typu do interfejsu.
Dzięki temu implementacja pozostaje wielokrotnego użytku dla dowolnego typu elementu.
using System.Collections.Generic;
class Store<T> : IRepository<T>
{
private readonly List<T> data = new();
public void Add(T item) => data.Add(item);
public T Get(int id) => data[id];
}
interface IRepository<T> { void Add(T item); T Get(int id); }IComparable<T> w działaniu
IComparable<T> to wbudowany interfejs generyczny. Jego implementacja pozwala określić sposób porządkowania instancji danego typu, co umożliwia sortowanie.
Metoda CompareTo zwraca wartość ujemną, zero lub wartość dodatnią.
class Money : IComparable<Money>
{
public int Cents;
public int CompareTo(Money? other)
=> Cents.CompareTo(other?.Cents ?? 0);
}Implementowanie IEnumerable<T>
IEnumerable<T> stanowi podstawę LINQ i instrukcji foreach. Typ, który go implementuje, można przeglądać za pomocą iteracji. Często deleguje się tę funkcję do iteratora wewnętrznej kolekcji.
Metody iteratorów z użyciem yield return ułatwiają to zadanie.
using System.Collections;
using System.Collections.Generic;
class Bag<T> : IEnumerable<T>
{
private readonly List<T> items = new();
public void Add(T x) => items.Add(x);
public IEnumerator<T> GetEnumerator() => items.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}Generyczny interfejs gotowy do uruchomienia
Ten kompletny program definiuje generyczny interfejs IPrinter<T>, implementuje go dla napisów, a następnie z niego korzysta.
Interfejs gwarantuje dostępność metody Print niezależnie od konkretnego typu.
using System;
interface IPrinter<T> { void Print(T value); }
class ConsolePrinter<T> : IPrinter<T>
{
public void Print(T value) => Console.WriteLine(value);
}
class Program
{
static void Main()
{
IPrinter<string> p = new ConsolePrinter<string>();
p.Print("hello generics");
}
}Kowariancja z out
Parametr interfejsu generycznego oznaczony jako out jest kowariantny: występuje wyłącznie w pozycjach wyjściowych. Dzięki temu IEnumerable<Cat> można użyć tam, gdzie oczekiwane jest IEnumerable<Animal>.
Kowariancja zachowuje zgodność przypisań w łańcuchu dziedziczenia.
interface IProducer<out T>
{
T Produce();
}Kontrawariancja z in
Parametr oznaczony jako in jest kontrawariantny: występuje wyłącznie w pozycjach wejściowych. Dzięki temu IComparer<Animal> można użyć tam, gdzie potrzebny jest IComparer<Cat>.
Kontrawariancja odwraca kierunek przypisywania w przypadku odbiorców danych.
interface IConsumer<in T>
{
void Consume(T item);
}Wiele parametrów typów
Interfejsy generyczne mogą przyjmować więcej niż jeden parametr. IDictionary<TKey, TValue> to znany przykład z oddzielnymi typami klucza i wartości.
Każdy parametr może niezależnie być niezmienny, kowariantny lub kontrawariantny.
interface IMapper<TIn, TOut>
{
TOut Map(TIn input);
}Programowanie względem interfejsu
Korzystanie z generycznego interfejsu zamiast konkretnej klasy sprawia, że kod jest elastyczny. Można zamieniać implementacje bez zmieniania kodu wywołującego.
Parametry metod o typie IEnumerable<T> akceptują zarówno listy i tablice, jak i wyniki zapytań.
using System.Collections.Generic;
using System.Linq;
int Total(IEnumerable<int> values) => values.Sum();Ograniczenia z użyciem interfejsów generycznych
Interfejsy generyczne często występują jako ograniczenia. where T : IComparable<T> pozwala metodzie sortować dane wejściowe lub je porównywać.
Łączy to dwie cechy generyków, umożliwiając tworzenie bezpiecznych i wielokrotnego użytku algorytmów.
T Min<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) <= 0 ? a : b;Szybki test
Sprawdź swoją wiedzę na temat interfejsów generycznych.
Podsumowanie
Interfejsy generyczne deklarują parametry typów i pozwalają implementacjom je ustalać lub przekazywać dalej. Wbudowane przykłady obejmują IEnumerable<T>, IComparable<T> oraz IDictionary<TKey, TValue>.
Adnotacje wariancji out i in umożliwiają kowariancję i kontrawariancję, a interfejsy generyczne naturalnie współpracują z ograniczeniami where.
Często zadawane pytania
Czy lekcja „Interfejsy generyczne” jest bezpłatna?
Tak — pełny tekst „Interfejsy generyczne” 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 „Interfejsy generyczne”?
Uogólni Pan/Pani rozwiązania względem 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 „Interfejsy generyczne”?
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
- Metody generyczne
- Klasy generyczne
- Ograniczenia where
- Interfejsy generyczne