Omezení

Toto téma popisuje omezení, která můžete použít u parametrů obecného typu k určení požadavků na argument typu v obecném typu nebo funkci.

Syntaxe

type-parameter-list when constraint1 [ and constraint2]

Poznámky

Existuje několik různých omezení, která můžete použít k omezení typů, které lze použít v obecném typu. Následující tabulka uvádí a popisuje tato omezení.

Omezení Syntaxe Popis
Omezení typu type-parameter :>type Zadaný typ musí být roven zadanému typu nebo odvozený od zadaného typu, nebo pokud je typem rozhraní, musí zadaný typ implementovat rozhraní.
Omezení null type-parameter : null Zadaný typ musí podporovat literál null. To zahrnuje všechny typy objektů .NET, ale ne seznam F#, řazenou kolekci členů, funkci, třídu, záznam nebo typy sjednocení.
Explicitní omezení členu [(]type-parameter [nebo ... nebo type-parameter)] : (member-signature) Alespoň jeden z zadaných argumentů typu musí mít člena, který má zadaný podpis; nejsou určeny pro běžné použití. Členy musí být buď explicitně definovány pro typ nebo část implicitního rozšíření typu, aby byly platnými cíli pro explicitní omezení člena.
Omezení konstruktoru type-parameter : ( new : unit -> 'a ) Zadaný typ musí mít konstruktor bez parametrů.
Omezení typu hodnoty type-parameter : struct Zadaný typ musí být typ hodnoty .NET.
Omezení typu odkazu type-parameter : not struct Zadaný typ musí být referenčním typem .NET.
Omezení typu výčtu type-parameter : enum<underlying-type> Zadaný typ musí být výčtový typ, který má zadaný základní typ; nejsou určeny pro běžné použití.
Omezení delegáta type-parameter : delegate<tuple-parameter-type, return-type> Zadaný typ musí být typ delegáta, který má zadané argumenty a návratovou hodnotu; nejsou určeny pro běžné použití.
Omezení porovnání type-parameter : comparison Zadaný typ musí podporovat porovnání.
Omezení rovnosti type-parameter : rovnost Zadaný typ musí podporovat rovnost.
Nespravované omezení type-parameter : nespravovaný Zadaný typ musí být nespravovaný typ. Nespravované typy jsou buď určité primitivní typy (sbyte, byte, char, nativeint, , unativeint, float32, int16uint32uint16floatint64uint64int32nebo decimal), výčtové typy, nebo negenerické struktury, nativeptr<_>jejichž pole jsou všechny nespravované typy.

Omezení musíte přidat, pokud váš kód musí používat funkci, která je k dispozici pro typ omezení, ale ne pro typy obecně. Pokud například použijete omezení typu k určení typu třídy, můžete použít některou z metod této třídy v obecné funkci nebo typu.

Určení omezení se někdy vyžaduje při explicitní zápisu parametrů typu, protože bez omezení nemá kompilátor žádný způsob, jak ověřit, zda budou funkce, které používáte, k dispozici u libovolného typu, který může být zadán za běhu parametru typu.

Nejběžnější omezení, která používáte v kódu jazyka F#, jsou omezení typu, která určují základní třídy nebo rozhraní. Další omezení používá knihovna F# k implementaci určitých funkcí, jako je například explicitní omezení členů, které se používá k implementaci přetížení operátoru pro aritmetické operátory, nebo jsou poskytovány hlavně proto, že jazyk F# podporuje úplnou sadu omezení podporovaných modulem CLR (Common Language Runtime).

Během procesu odvozování typu se kompilátor automaticky odvodí některá omezení. Pokud například použijete + operátor ve funkci, kompilátor odvodí explicitní omezení členu u typů proměnných, které se ve výrazu používají.

Následující kód znázorňuje některé deklarace omezení:

// Base Type Constraint
type Class1<'T when 'T :> System.Exception> =
    class end

// Interface Type Constraint
type Class2<'T when 'T :> System.IComparable> =
    class end

// Null constraint
type Class3<'T when 'T : null> =
    class end

// Member constraint with instance member
type Class5<'T when 'T : (member Method1 : 'T -> int)> =
    class end

// Member constraint with property
type Class6<'T when 'T : (member Property1 : int)> =
    class end

// Constructor constraint
type Class7<'T when 'T : (new : unit -> 'T)>() =
    member val Field = new 'T()

// Reference type constraint
type Class8<'T when 'T : not struct> =
    class end

// Enumeration constraint with underlying value specified
type Class9<'T when 'T : enum<uint32>> =
    class end

// 'T must implement IComparable, or be an array type with comparable
// elements, or be System.IntPtr or System.UIntPtr. Also, 'T must not have
// the NoComparison attribute.
type Class10<'T when 'T : comparison> =
    class end

// 'T must support equality. This is true for any type that does not
// have the NoEquality attribute.
type Class11<'T when 'T : equality> =
    class end

type Class12<'T when 'T : delegate<obj * System.EventArgs, unit>> =
    class end

type Class13<'T when 'T : unmanaged> =
    class end

// Member constraints with two type parameters
// Most often used with static type parameters in inline functions
let inline add(value1 : ^T when ^T : (static member (+) : ^T * ^T -> ^T), value2: ^T) =
    value1 + value2

// ^T and ^U must support operator +
let inline heterogenousAdd(value1 : ^T when (^T or ^U) : (static member (+) : ^T * ^U -> ^T), value2 : ^U) =
    value1 + value2

// If there are multiple constraints, use the and keyword to separate them.
type Class14<'T,'U when 'T : equality and 'U : equality> =
    class end

Viz také