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