Einschränkungen

Erfahren Sie mehr über Einschränkungen, die für generische Typparameter gelten, um die Anforderungen für ein Typargument in einem generischen Typ oder einer generischen Funktion anzugeben.

Syntax

type-parameter-list when constraint1 [ and constraint2]

Hinweise

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 Protokolldateien aufgelistet und beschrieben.

Einschränkung Syntax BESCHREIBUNG
Typeinschränkung type-parameter :>type Der bereitgestellte Typ muss gleich dem angegebenen Typ sein oder davon abgeleitet sein, oder, wenn der Typ eine Schnittstelle ist, muss der bereitgestellte Typ die Schnittstelle implementieren.
Null-Einschränkung type-parameter : null Der angegebene Typ muss das Null-Literal unterstützen. Dies umfasst alle .NET-Objekttypen, aber nicht F#-Listen-, Tupel-, Funktions-, Klassen-, Datensatz- oder Union-Typen.
Explizite Membereinschränkung [(]type-parameter [or ... or type-parameter)] : (member-signature) Mindestens eines der angegebenen Typargumente muss über einen Member mit der angegebenen Signatur verfügen. Dies ist nicht für den allgemeinen Gebrauch 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 type-parameter : ( new : unit -> 'a ) Die angegebene Klasse muss einen parameterlosen Konstruktor haben.
Werttypeinschränkung type-parameter : struct Der angegebene Typ muss ein .NET-Werttyp sein.
Verweistypeinschränkung type-parameter : not struct Der angegebene Typ muss ein .NET-Verweistyp sein.
Enumerationtypeinschränkung type-parameter : enum<underlying-type> Der bereitgestellte Typ muss ein enumerierter Typ sein, der über den angegebenen zugrunde liegenden Typ verfügt. Dies ist nicht für den allgemeinen Gebrauch vorgesehen.
Delegateinschränkung type-parameter : delegate<tuple-parameter-type, return-type> Der angegebene Typ muss ein Delegattyp sein, der über die angegebenen Argumente und den angegebenen Rückgabewert verfügt. Dies ist nicht für den allgemeinen Gebrauch vorgesehen.
Vergleichseinschränkung type-parameter : comparison Der angegebene Typ muss einen Vergleich unterstützen.
Gleichheitseinschränkung type-parameter : equality Der angegebene Typ muss einen Vergleich unterstützen.
Nicht verwaltete Einschränkungen type-parameter : unmanaged Das Typargument muss ein nicht verwalteter Typ sein. Nicht verwaltete Typen sind entweder bestimmte primitive Typen (sbyte, byte, char, nativeint, unativeint, float32, float, int16, uint16, int32, uint32, int64, uint64 oder decimal), Enumerationstypen, oder eine nicht generische Struktur, nativeptr<_>, oder eine nicht-generische Struktur, deren Felder alle nicht verwaltete 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 generischen Typ verwenden.

Die Angabe von Beschränkungen ist manchmal erforderlich, wenn Typparameter explizit geschrieben werden, da der Compiler ohne eine Beschränkung keine Möglichkeit hat, zu überprüfen, ob die von Ihnen verwendeten Funktionen auf jedem Typ verfügbar sind, der zur Laufzeit für den Typparameter geliefert werden könnte.

Die häufigsten Einschränkungen, die Sie in 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 von Operatorüberladungen für arithmetische Operatoren verwendet wird, oder werden hauptsächlich bereitgestellt, weil F# den vollständigen Satz von Einschränkungen unterstützt, der von der Common Language Runtime unterstützt wird.

Während des Typrückschlussprozesses werden einige Einschränkungen automatisch vom Compiler abgeleitet. Wenn Sie beispielsweise den + Operator in einer Funktion verwenden, leitet der Compiler eine explizite Membereinschränkung auf Variablentypen 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

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