Freigeben über


Zwänge

In diesem Thema werden Einschränkungen beschrieben, die Sie auf generische Typparameter anwenden können, um die Anforderungen für ein Typargument in einem generischen Typ oder einer generischen Funktion anzugeben.

Syntax

type-parameter-list when constraint1 [ and constraint2]

Bemerkungen

Es gibt verschiedene Einschränkungen, die Sie anwenden können, um die Typen einzuschränken, die in einem generischen Typ verwendet werden können. In der folgenden Tabelle sind diese Einschränkungen aufgeführt und beschrieben.

Zwang Syntax Beschreibung
Typeinschränkung Typparameter :>Typ Der angegebene Typ muss dem angegebenen Typ entsprechen oder vom angegebenen Typ abgeleitet sein, oder, wenn der Typ eine Schnittstelle ist, muss der bereitgestellte Typ die Schnittstelle implementieren.
Null-Einschränkung Typparameter : null Der angegebene Typ muss den Nullwert unterstützen. Dazu gehören alle .NET-Objekttypen, jedoch keine F#-Liste, Tupel, Funktion, Klasse, Datensatz oder Union-Typen.
Not Null-Einschränkung type-parameter : not null Der angegebene Typ darf den Nullwert nicht unterstützen. Dadurch sind sowohl mit null kommentierte Typen nicht zulässig als auch Typen, die null als Darstellungswert aufweisen (z. B. der Optionstyp oder Typen, die mit dem AllowNullLiteral-Attribut definiert sind). Diese generische Einschränkung lässt Werttypen zu, da diese niemals null sein können.
Explizite Mitgliederbeschränkung [(]type-parameter [or ... or type-parameter)] : (member-signature) Mindestens eines der angegebenen Typargumente muss über ein Element verfügen, das über die angegebene Signatur verfügt; nicht für die gemeinsame Verwendung vorgesehen. Member müssen entweder explizit für den Typ oder teil einer impliziten Typerweiterung definiert werden, um gültige Ziele für eine Explizite Membereinschränkung zu sein.
Konstruktoreinschränkung Typparameter : ( neu : einheit -> 'a ) Der angegebene Typ muss über einen parameterlosen Konstruktor verfügen.
Werttypeinschränkung typparameter : struktur Der angegebene Typ muss ein .NET-Werttyp sein.
Referenztypeinschränkung type-parameter : not struct Der angegebene Typ muss ein .NET-Verweistyp sein.
Enumerationstypeinschränkung type-parameter : enum<underlying-type> Der angegebene Typ muss ein Aufzählungstyp sein, der den angegebenen zugrunde liegenden Typ aufweist; nicht für allgemeinen Gebrauch vorgesehen.
Delegierungseinschränkung type-parameter : delegate<tuple-parameter-type, return-type> Der angegebene Typ muss ein Delegattyp sein, der die angegebenen Argumente und den Rückgabewert hat; er ist nicht für den allgemeinen Gebrauch bestimmt.
Vergleichseinschränkung Typ-Parameter: Vergleich Der angegebene Typ muss den Vergleich unterstützen.
Gleichheitseinschränkung Typparameter : Gleichheit Der bereitgestellte Typ muss die Gleichheit unterstützen.
Nicht verwaltete Einschränkung type-parameter : unmanaged Der angegebene Typ muss ein nicht verwalteter Typ sein. Nicht verwaltete Typen sind entweder bestimmte Grundtypen (sbyte, byte, char, nativeint, unativeint, float32, float, int16, uint16, int32, uint32, int64, uint64oder decimal), Enumerationstypen, nativeptr<_>oder eine nicht generische Struktur, deren Felder alle nicht verwalteten Typen sind.

Sie müssen eine Einschränkung hinzufügen, wenn Ihr Code ein Feature verwenden muss, das für den Einschränkungstyp verfügbar ist, aber nicht für Typen im Allgemeinen. Wenn Sie beispielsweise die Typeinschränkung verwenden, um einen Klassentyp anzugeben, können Sie eine der Methoden dieser Klasse in der generischen Funktion oder dem Typ verwenden.

Die Angabe von Einschränkungen ist manchmal erforderlich, wenn Typparameter explizit geschrieben werden, da der Compiler ohne Einschränkung keine Möglichkeit hat, zu überprüfen, ob die von Ihnen verwendeten Features für jeden Typ verfügbar sind, der zur Laufzeit für den Typparameter bereitgestellt werden kann.

Die gängigsten Einschränkungen, die Sie im F#-Code verwenden, sind Typeinschränkungen, die Basisklassen oder Schnittstellen angeben. Die anderen Einschränkungen werden entweder von der F#-Bibliothek verwendet, um bestimmte Funktionen zu implementieren, z. B. die explizite Membereinschränkung, die zum Implementieren der Operatorüberladung für arithmetische Operatoren verwendet wird, oder werden hauptsächlich bereitgestellt, da F# den vollständigen Satz von Einschränkungen unterstützt, die von der Common Language Runtime unterstützt werden.

Während des Typinferenzprozesses werden einige Constraints automatisch vom Compiler abgeleitet. Wenn Sie beispielsweise den +-Operator in einer Funktion verwenden, leitet der Compiler eine explizite Membereinschränkung für variablen Typen ab, die im Ausdruck verwendet werden.

Der folgende Code veranschaulicht einige Einschränkungsdeklarationen:

// 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

Siehe auch