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

Klauzule where v obecné definici určuje omezení typů, které se používají jako argumenty pro parametry typu v obecném typu, metodě, delegátu nebo místní funkci. Omezení mohou určovat rozhraní, základní třídy nebo vyžadovat obecný typ, aby byl odkaz, hodnota nebo nespravovaný typ. Deklarují schopnosti, které musí mít argument typu, a musí být umístěny po jakékoli deklarované základní třídě nebo implementovaných rozhraních.

Můžete například deklarovat obecnou třídu, AGenericClassaby parametr T typu 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 klauzuli where.

Klauzule where může také zahrnovat 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 tato základní třída. Pokud se použije omezení základní třídy, musí se zobrazit před všemi dalšími omezeními daného parametru typu. Některé typy jsou zakázány jako omezení základní třídy: Object, Arraya ValueType. 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 je vynucena nullability základního typu třídy. Pokud je základní třída nenulová (například Base), musí být argument typu nenulový. Pokud je základní třída nullable (například Base?), může být argument typu nullable nebo nenulový odkazový typ. Kompilátor vydá upozornění v případě, že argument typu je odkazovatelný typ null, pokud základní třída není nullable.

Klauzule where může určit, že typ je nebo class struct. Omezení struct odebere nutnost zadat omezení System.ValueTypezákladní třídy . Typ System.ValueType nelze použít jako omezení základní třídy. Následující příklad ukazuje omezení class i struct omezení:

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

V kontextu s možnou class hodnotou null vyžaduje omezení, aby typ byl nenulový odkazový typ. Chcete-li povolit odkazové typy s možnou class? hodnotou null, použijte omezení, které umožňuje odkazové typy s možnou hodnotou null i bez hodnoty null.

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

Přidání referenčních typů s možnou hodnotou null představuje potenciální nejednoznačnost ve významu T? obecných metod. Pokud T je , structT? je stejný jako System.Nullable<T>. Pokud T je však typ odkazu, znamená to, T? že null je platná hodnota. Nejednoznačnost vzniká, protože přepsání metod nemůže zahrnovat omezení. Nové default omezení tuto nejednoznačnost vyřeší. Přidáte ho, když základní třída nebo rozhraní deklaruje dvě přetížení metody, jedna, která určuje struct omezení a jedna, která nemá buď struct použité omezení, nebo class omezení:

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

}

Pomocí default omezení určíte, že odvozená třída přepíše metodu bez omezení v odvozené třídě nebo explicitní implementace rozhraní. Platí pouze pro metody, které přepisují 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é obsahují omezení, lze použít v nezapomnělém kontextu s možnou notnull hodnotou null, ale kompilátor nevynucuje omezení.

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

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

class UnManagedWrapper<T>
    where T : unmanaged
{ }

Klauzule where může také obsahovat omezení konstruktoru, new(). Toto omezení umožňuje vytvořit instanci parametru typu pomocí operátoru new . Omezení new() kompilátoru informuje, že jakýkoli zadaný argument typu musí mít přístupný konstruktor bez parametrů. Pří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, pokud nebude následovat allows ref struct anti-constraint. Omezení new() nelze kombinovat s omezenímistruct.unmanaged Všechny typy, které splňují tato omezení, musí mít přístupný konstruktor bez parametrů, aby new() bylo omezení redundantní.

Toto anti-constraint deklaruje, že argument typu může T být ref struct typ. Příklad:

public class GenericRefStruct<T> where T : allows ref struct
{
    // Scoped is allowed because T might be a ref struct
    public void M(scoped T parm)
    {

    }
}

Obecný typ nebo metoda musí dodržovat pravidla bezpečnosti ref pro libovolnou ref structinstanci, protože T může být . Klauzuli allows ref struct nelze kombinovat s class omezením.class? Anti-constraint allows ref struct musí dodržovat všechna omezení pro tento argument typu.

U více parametrů typu použijte jednu where klauzuli pro každý parametr typu, 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 také připojit 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 popisování 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é