where (omezení obecného typu) (Referenční dokumentace jazyka C#)

Klauzule v obecné definici určuje omezení typů, které se používají jako argumenty pro parametry typu v obecném where typu, metodě, delegátovi nebo místní funkci. Omezení mohou specifikovat rozhraní, základní třídy nebo vyžadovat, aby obecný typ byl odkaz, hodnota nebo nespravovaný typ. Deklarují schopnosti, které musí mít argument typu.

Můžete například deklarovat obecnou třídu , tak, aby parametr AGenericClass typu T implementuje IComparable<T> rozhraní:

public class AGenericClass<T> where T : IComparable<T> { }

Poznámka

Další informace o klauzuli where ve výrazu dotazu najdete v tématu klauzule where.

Klauzule where může také obsahovat omezení základní třídy. Omezení základní třídy uvádí, že typ, který se má použít jako argument typu pro tento obecný typ, má zadanou třídu jako základní třídu nebo je základní třídou. Pokud se použije omezení základní třídy, musí se objevit před dalšími omezeními tohoto parametru typu. Některé typy jsou zakázány jako omezení základní třídy: , a Object Array ValueType . Před C# 7.3 byly , a také zakázány jako Enum Delegate omezení základní MulticastDelegate třídy. Následující příklad ukazuje typy, které lze nyní zadat jako základní třídu:

public class UsingEnum<T> where T : System.Enum { }

public class UsingDelegate<T> where T : System.Delegate { }

public class Multicaster<T> where T : System.MulticastDelegate { }

V kontextu s možnou hodnotou null v jazyce C# 8.0 a novějším je vynucována možnost null pro typ základní třídy. Pokud základní třída nemůže mít hodnotu null (například ), argument typu musí Base být bez nullable. Pokud je základní třída s možnou hodnotou null (například ), může být argument typu odkaz s možnou hodnotou null nebo odkaz s možnou Base? hodnotou null. Kompilátor vydá upozornění, pokud je argument typu odkaz s možnou hodnotou null, pokud základní třída nemůže mít hodnotu null.

Klauzule where může určit, že typ je class nebo struct . Toto omezení eliminuje potřebu určit omezení struct základní třídy System.ValueType třídy . Typ System.ValueType nemusí být použit jako omezení základní třídy. Následující příklad ukazuje omezení class struct i :

class MyClass<T, U>
    where T : class
    where U : struct
{ }

V kontextu s možnou hodnotou null v jazyce C# 8.0 a novějším vyžaduje omezení typ odkazu, který není class nullable. Pokud chcete povolit odkazové typy s možnou hodnotou null, použijte omezení, které umožňuje odkazové typy s možnou hodnotou null i odkaz s možnou class? hodnotou null.

Klauzule where může obsahovat notnull omezení. Omezení notnull omezuje parametr typu na typy s možnou hodnotou null. Typ může být typ hodnoty nebo odkazový typ s možnou hodnotou null. Omezení notnull je k dispozici počínaje jazykem C# 8.0 pro kód zkompilovaný v nullable enable kontextu. Na rozdíl od jiných omezení, pokud argument typu porušuje omezení, kompilátor notnull místo chyby vygeneruje upozornění. Upozornění se generují pouze v nullable enable kontextu.

Přidání odkazových typů s možnou hodnotou null zavádí potenciální nejednoznačnost ve smyslu v T? obecných metodách. Pokud T je , je stejný jako struct T? System.Nullable<T> . Pokud je T však odkazový typ, T? znamená null to, že je platná hodnota. K této nejednoznačnosti dochází, protože přepisovací metody nemůže obsahovat omezení. Toto default nejednoznačnost řeší nové omezení. Přidáte ho, když základní třída nebo rozhraní deklaruje dvě přetížení metody, jedno, které určuje omezení, a jedno, které nemá použité omezení struct struct nebo class :

public abstract class B
{
    public void M<T>(T? item) where T : struct { }
    public abstract void M<T>(T? item);

}

Omezení použijete k určení, že odvozená třída přepíše metodu bez omezení v odvozené třídě nebo explicitní default implementace rozhraní. Je platný pouze u metod, které přepíší základní metody, nebo explicitní implementace rozhraní:

public class D : B
{
    // Without the "default" constraint, the compiler tries to override the first method in B
    public override void M<T>(T? item) where T : default { }
}

Důležité

Obecné deklarace, které zahrnují omezení, lze použít v zapomenutí kontextu s možnou hodnotou null, ale kompilátor toto omezení notnull nevynucuje.

#nullable enable
    class NotNullContainer<T>
        where T : notnull
    {
    }
#nullable restore

Klauzule where může obsahovat také unmanaged omezení. Omezení unmanaged omezuje parametr typu na typy označované jako nespravované typy. Toto omezení usnadňuje psaní kódu zprostředkovatele komunikace nízké úrovně unmanaged v jazyce C#. Toto omezení umožňuje opětovné použití rutin napříč všemi nespravovanými typy. Omezení unmanaged nelze kombinovat s class struct omezením nebo . Omezení unmanaged vynucuje, že typ musí být struct :

class UnManagedWrapper<T>
    where T : unmanaged
{ }

Klauzule where může obsahovat také omezení konstruktoru new() . Toto omezení umožňuje vytvořit instanci parametru typu pomocí new operátoru . Omezení new() umožňuje kompilátoru vědět, že jakýkoli zadaný argument typu musí mít přístupný konstruktor bez parametrů. Například:

public class MyGenericClass<T> where T : IComparable<T>, new()
{
    // The following line is not possible without new() constraint:
    T item = new T();
}

Omezení new() se zobrazí jako poslední v where klauzuli . Omezení new() nelze kombinovat s struct omezeními unmanaged nebo . Všechny typy, které splňují tato omezení, musí mít přístupný konstruktor bez parametrů, takže new() omezení je redundantní.

U více parametrů typu použijte pro každý parametr typu jednu where klauzuli, například:

public interface IMyInterface { }

namespace CodeExample
{
    class Dictionary<TKey, TVal>
        where TKey : IComparable<TKey>
        where TVal : IMyInterface
    {
        public void Add(TKey key, TVal val) { }
    }
}

Omezení můžete připojit také k parametrům typů obecných metod, jak je znázorněno v následujícím příkladu:

public void MyMethod<T>(T t) where T : IMyInterface { }

Všimněte si, že syntaxe popisující omezení parametrů typu u delegátů je stejná jako u metod:

delegate T MyDelegate<T>() where T : new();

Informace o obecných delegátech najdete v tématu Obecné delegáty.

Podrobnosti o syntaxi a použití omezení najdete v tématu Omezení parametrů typu.

specifikace jazyka C#

Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.

Viz také