Megosztás a következőn keresztül:


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, floatuint32uint16int16int64uint64int32decimal), 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

Lásd még