Megszorítások
Ez a témakör azokat a korlátozásokat ismerteti, amelyeket általános típusparaméterekre alkalmazhat egy típusargumentum követelményeinek általános típusban vagy függvényben való megadásához.
Syntax
type-parameter-list when constraint1 [ and constraint2]
Megjegyzések
Az általános típusban használható típusok korlátozására számos különböző korlátozás alkalmazható. Az alábbi táblázat felsorolja és ismerteti ezeket a korlátozásokat.
Megszorítás | Szintaxis | Leírás |
---|---|---|
Típusmegkötés | type-parameter :>type | A megadott típusnak meg kell egyenlõnek vagy származnia a megadott típusból, vagy ha a típus interfész, akkor a megadott típusnak implementálnia kell az interfészt. |
Null kényszer | type-parameter : null | A megadott típusnak támogatnia kell a null literált. Ez magában foglalja az összes .NET-objektumtípust, de nem az F# listát, a rekordot, a függvényt, az osztályt, a rekordot vagy az egyesítő típust. |
Explicit tagkorlátozás | [(]type-parameter [vagy ... vagy type-parameter)] : (tag-aláírás) | A megadott típusargumentumok legalább egyikének rendelkeznie kell a megadott aláírással rendelkező tagdal; nem közös használatra szántak. A tagokat explicit módon kell definiálni egy implicit típusú bővítmény típusán vagy részén, hogy érvényes célként szerepeljenek egy explicit tagkorlátozás esetében. |
Konstruktor-kényszer | type-parameter : ( new : unit -> 'a ) | A megadott típusnak paraméter nélküli konstruktorsal kell rendelkeznie. |
Értéktípus-korlátozás | type-parameter : struct | A megadott típusnak .NET-értéktípusnak kell lennie. |
Hivatkozástípus-korlátozás | type-parameter : not struct | A megadott típusnak .NET-referenciatípusnak kell lennie. |
Számbavételi típus kényszere | type-parameter : enum<underlying-type> | A megadott típusnak számba kell vennie a megadott mögöttes típust; nem közös használatra szántak. |
Delegálási kényszer | type-parameter : delegált<tuple-parameter-type, return-type> | A megadott típusnak olyan meghatalmazotttípusnak kell lennie, amely rendelkezik a megadott argumentumokkal és visszatérési értékkel; nem közös használatra szántak. |
Összehasonlító kényszer | type-parameter : comparison | A megadott típusnak támogatnia kell az összehasonlítást. |
Egyenlőségi kényszer | type-parameter : egyenlőség | A megadott típusnak támogatnia kell az egyenlőséget. |
Nem felügyelt kényszer | type-parameter : unmanaged | A megadott típusnak nem felügyelt típusnak kell lennie. A nem felügyelt típusok vagy bizonyos primitív típusok (sbyte , byte , char , nativeint , unativeint , float32 , float uint32 uint16 int16 int64 uint64 int32 decimal ), számbavételi típusok, vagy olyan nem általános szerkezetek, nativeptr<_> amelyek mezői mind nem felügyelt típusok. |
Kényszert kell hozzáadnia, ha a kódnak olyan funkciót kell használnia, amely elérhető a kényszertípuson, de általában nem a típusokon. Ha például a típusmegkötést használja egy osztálytípus megadásához, az osztály bármely metódusát használhatja az általános függvényben vagy típusban.
A típusparaméterek explicit írásakor néha szükség van korlátozások megadására, mert kényszer nélkül a fordító nem tudja ellenőrizni, hogy a használt funkciók elérhetők lesznek-e a típusparaméter futásidejű verziójában.
Az F#-kódban leggyakrabban használt kényszerek az alaposztályokat vagy interfészeket meghatározó típuskorlátozások. A többi korlátozást az F#-kódtár bizonyos funkciók implementálásához használja, például az explicit tagkorlátot, amely az operátorok túlterhelését valósítja meg az aritmetikai operátorok esetében, vagy főként azért, mert az F# támogatja a közös nyelvi futtatókörnyezet által támogatott korlátozások teljes készletét.
A típuskövetkeztetési folyamat során a fordító bizonyos korlátozásokat automatikusan kikövetkeztet. Ha például egy függvényben használja az +
operátort, a fordító explicit tagkorlátozást keres a kifejezésben használt változótípusokra vonatkozóan.
Az alábbi kód néhány kényszerdeklarációt szemléltet:
// 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