Beperkingen
In dit onderwerp worden beperkingen beschreven die u kunt toepassen op algemene typeparameters om de vereisten voor een typeargument in een algemeen type of functie op te geven.
Syntaxis
type-parameter-list when constraint1 [ and constraint2]
Opmerkingen
Er zijn verschillende beperkingen die u kunt toepassen om de typen te beperken die in een algemeen type kunnen worden gebruikt. In de volgende tabel worden deze beperkingen vermeld en beschreven.
Beperking | Syntaxis | Beschrijving |
---|---|---|
Typebeperking | type-parameter :>type | Het opgegeven type moet gelijk zijn aan of zijn afgeleid van het opgegeven type of, als het type een interface is, moet het opgegeven type de interface implementeren. |
Null-beperking | type-parameter : null | Het opgegeven type moet ondersteuning bieden voor de letterlijke waarde null. Dit omvat alle .NET-objecttypen, maar niet de F#-lijst, tuple, functie, klasse, record of samenvoegingstypen. |
Expliciete lidbeperking | [(]type-parameter [of ... of type-parameter)] : (lidhandtekening) | Ten minste één van de opgegeven typeargumenten moet een lid hebben met de opgegeven handtekening; niet bedoeld voor gemeenschappelijk gebruik. Leden moeten expliciet worden gedefinieerd voor het type of een deel van een impliciete typeextensie als geldige doelen voor een expliciete lidbeperking. |
Constructorbeperking | type-parameter : ( nieuw : eenheid -> 'a ) | Het opgegeven type moet een parameterloze constructor hebben. |
Waardetypebeperking | type-parameter : struct | Het opgegeven type moet een .NET-waardetype zijn. |
Beperking verwijzingstype | type-parameter : niet struct | Het opgegeven type moet een .NET-verwijzingstype zijn. |
Opsommingstypebeperking | type-parameter : enum<onderliggende-type> | Het opgegeven type moet een geïnventariseerd type zijn dat het opgegeven onderliggende type heeft; niet bedoeld voor gemeenschappelijk gebruik. |
Beperking delegeren | type-parameter : delegate<tuple-parameter-type, return-type> | Het opgegeven type moet een gemachtigdentype zijn met de opgegeven argumenten en retourwaarde; niet bedoeld voor gemeenschappelijk gebruik. |
Vergelijkingsbeperking | type-parameter : vergelijking | Het opgegeven type moet ondersteuning bieden voor vergelijking. |
Gelijkheidsbeperking | type-parameter : gelijkheid | Het opgegeven type moet gelijkheid ondersteunen. |
Onbeheerde beperking | type-parameter : onbeheerd | Het opgegeven type moet een niet-beheerd type zijn. Niet-beheerde typen zijn bepaalde primitieve typen (sbyte , , , nativeint char , , float float32 uint16 int32 uint32 int16 unativeint , , int64 , uint64 of decimal ), opsommingstypen, nativeptr<_> of een niet-algemene structuur waarvan de velden allemaal niet-beheerde typen zijn. byte |
U moet een beperking toevoegen wanneer uw code een functie moet gebruiken die beschikbaar is voor het beperkingstype, maar niet voor typen in het algemeen. Als u bijvoorbeeld de typebeperking gebruikt om een klassetype op te geven, kunt u een van de methoden van die klasse in de algemene functie of het type gebruiken.
Het opgeven van beperkingen is soms vereist bij het expliciet schrijven van typeparameters, omdat de compiler zonder beperking geen manier heeft om te controleren of de functies die u gebruikt, beschikbaar zijn voor elk type dat tijdens runtime kan worden opgegeven voor de typeparameter.
De meest voorkomende beperkingen die u in F#-code gebruikt, zijn typebeperkingen waarmee basisklassen of interfaces worden opgegeven. De andere beperkingen worden gebruikt door de F#-bibliotheek om bepaalde functionaliteit te implementeren, zoals de expliciete lidbeperking, die wordt gebruikt voor het implementeren van operatoroverbelasting voor rekenkundige operators, of worden voornamelijk geleverd omdat F# de volledige set beperkingen ondersteunt die worden ondersteund door de runtime van de algemene taal.
Tijdens het typedeductieproces worden sommige beperkingen automatisch afgeleid door de compiler. Als u bijvoorbeeld de +
operator in een functie gebruikt, wordt door de compiler een expliciete lidbeperking afgeleid van variabeletypen die in de expressie worden gebruikt.
De volgende code illustreert enkele beperkingsdeclaraties:
// 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