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.
Syntax
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í | Syntax | Popis |
---|---|---|
Omezení typu | typ parametru:>typ | 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 | parametr typu : null | Zadaný typ musí podporovat hodnotu null. To zahrnuje všechny typy objektů .NET, ale ne seznam F#, řazenou kolekci členů, funkci, třídu, záznam nebo typy sjednocení. |
Omezení nenulovosti | parametr typu: není null | Zadaný typ nesmí podporovat hodnotu null. To zakáže jak null anotované typy, tak typy, které mají hodnotu reprezentace null (například typ možnosti nebo typy definované atributem AllowNullLiteral). Toto obecné omezení povoluje typy hodnot, protože tyto typy nemohou být nikdy null. |
Explicitní omezení členu | [(]typ-parametr [nebo ... nebo typ-parametr)] : (člen-podpis) | 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 na typu, nebo jako součást implicitního rozšíření typu, aby byly platnými cíli pro explicitní omezení člena. |
Omezení konstruktoru | parametr typu: (nová: jednotka -> 'a) | Zadaný typ musí mít konstruktor bez parametrů. |
Omezení typu hodnoty | parametr typu: struktura | Zadaný typ musí být typ hodnoty .NET. |
Omezení typu odkazu | parametr typu: není struktura | Zadaný typ musí být referenčním typem .NET. |
Omezení typu výčtu | parametr typu: výčet<podkladového typu> | 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 | typ parametru : delegát<typ parametru n-tice, návratový typ> | 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í | parametr typu: porovnání | Zadaný typ musí podporovat porovnání. |
Omezení rovnosti | typový parametr: rovnost | Zadaný typ musí podporovat rovnost. |
Nespravované omezení | typ parametru: nespravovaný | Zadaný typ musí být nespravovaný typ. Nespravované typy jsou buď určité primitivní typy (sbyte , byte , char , nativeint , unativeint , float32 , float , int16 , uint16 , int32 , uint32 , int64 , uint64 nebo decimal ), typy výčtu, nativeptr<_> nebo negenerické struktury, 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 jsou některá omezení automaticky odvozena kompilátorem. Pokud například použijete operátor +
ve funkci, kompilátor odvodí explicitní omezení členu u typů proměnných používaných ve výrazu.
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
// Not Null constraint
type Class4<'T when 'T : not 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