Ograniczenia where
Ograniczy Pan/Pani parametry typów.
Ograniczenia where to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 3 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.
Dlaczego istnieją ograniczenia
Domyślnie parametr typu T jest traktowany niemal jak object, więc kompilator zezwala na bardzo niewiele operacji na nim. Ograniczenia zapisywane za pomocą where dostarczają kompilatorowi więcej informacji o T.
Dzięki tej wiedzy można bezpiecznie wywoływać metody, tworzyć instancje lub porównywać wartości.
void Show<T>(T value) where T : IFormattable
{
// now ToString(format, provider) is available
}Ograniczenia interfejsu
Ograniczenie interfejsu wymaga, aby T implementował określony interfejs. Treść metody może wtedy wywoływać składowe tego interfejsu.
W poniższym przykładzie where T : IComparable<T> gwarantuje istnienie metody CompareTo.
T Max<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) >= 0 ? a : b;Ograniczenia klasy bazowej
Można wymagać, aby T dziedziczył po określonej klasie bazowej. Wówczas wewnątrz kodu generycznego można używać składowych tego typu bazowego.
Jest to częste w strukturach, w których wszystkie encje mają wspólny typ bazowy.
class Animal { public string Name = ""; }
string NameOf<T>(T a) where T : Animal => a.Name;Ograniczenie class
where T : class wymaga, aby T był typem referencyjnym. Umożliwia to przypisywanie null i sprawdzanie równości referencji.
Jest to typowe w repozytoriach, pamięciach podręcznych i wszędzie tam, gdzie przechowuje się dopuszczające null referencje.
T? FindOrNull<T>(bool found, T value) where T : class
=> found ? value : null;Ograniczenie struct
where T : struct wymaga, aby T był niepustym typem wartości. Pozwala to traktować T jako typ wartości i używać T? jako typu wartości dopuszczającego null.
Stosuje się je w pomocniczych elementach działających wyłącznie z liczbami, wyliczeniami lub małymi strukturami.
T? AsNullable<T>(T value) where T : struct
=> value;Ograniczenie new()
Ograniczenie new() wymaga, aby T miał publiczny konstruktor bez parametrów. W treści metody można wtedy zapisać new T().
Fabryki i pule obiektów korzystają z tego mechanizmu, aby generycznie tworzyć instancje.
using System;
class Program
{
static T Make<T>() where T : new() => new T();
static void Main()
{
var list = Make<System.Collections.Generic.List<int>>();
Console.WriteLine(list.Count);
}
}Łączenie ograniczeń
Do jednego parametru można zastosować kilka ograniczeń. Reguły kolejności wymagają umieszczenia najpierw class lub struct, następnie klasy bazowej, potem interfejsów, a na końcu new().
Ograniczenia wymienia się po jednej klauzuli where, oddzielając je przecinkami.
T Build<T>() where T : class, IComparable<T>, new()
=> new T();Wiele klauzul where
Gdy metoda lub klasa ma kilka parametrów typu, każdy z nich otrzymuje własną klauzulę where. Klauzule zapisuje się jedna po drugiej.
Dzięki temu ograniczenia każdego parametru są wyraźnie oddzielone.
TResult Convert<TInput, TResult>(TInput x)
where TInput : class
where TResult : new()
=> new TResult();Przykład ograniczenia gotowy do uruchomienia
Ten kompletny program używa ograniczenia IComparable<T>, aby znaleźć większą z dwóch wartości, działając zarówno dla liczb całkowitych, jak i napisów.
To ograniczenie sprawia, że wywołanie CompareTo wewnątrz metody jest dozwolone.
using System;
class Program
{
static T Max<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) >= 0 ? a : b;
static void Main()
{
Console.WriteLine(Max(3, 9));
Console.WriteLine(Max("apple", "pear"));
}
}Ograniczenia notnull i unmanaged
Nowsze wersje języka C# dodają więcej ograniczeń. where T : notnull zabrania typów dopuszczających null, co jest przydatne w przypadku kluczy słowników. where T : unmanaged ogranicza T do typów wartości o układzie zgodnym z reprezentacją binarną, używanych w kodzie niskopoziomowym.
Ograniczenia te zwiększają bezpieczeństwo w wyspecjalizowanych zastosowaniach.
void Use<T>(T key) where T : notnull { }
unsafe void Raw<T>(T v) where T : unmanaged { }Ograniczenia odblokowują możliwości, a nie je ograniczają
Choć wyglądają jak ograniczenia, w rzeczywistości odblokowują dodatkowe możliwości. Bez ograniczenia można niewiele zrobić z T, a po jego zastosowaniu zyskuje się dostęp do odpowiednich składowych.
Należy wybrać minimalne ograniczenie, które pozwala działać algorytmowi, aby parametr typu pozostał możliwie elastyczny.
// No constraint: only object members available
string Name<T>(T x) => x.ToString();Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat ograniczeń where.
Podsumowanie
Klauzula where ogranicza parametry typu za pomocą interfejsu, klasy bazowej, class, struct, new(), notnull lub unmanaged. Każde ograniczenie odblokowuje określone operacje na T.
Należy stosować je we właściwej kolejności, używać jednej klauzuli dla każdego parametru i wybierać minimalne ograniczenie wymagane przez algorytm.
Często zadawane pytania
Czy lekcja „Ograniczenia where” jest bezpłatna?
Tak — pełny tekst „Ograniczenia where” 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 „Ograniczenia where”?
Ograniczy Pan/Pani parametry 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 3 z 4.
Ile czasu zajmuje lekcja „Ograniczenia where”?
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