Ограничения
В этом разделе описываются ограничения, которые можно применить к параметрам универсального типа, чтобы указать требования к аргументу типа в универсальном типе или функции.
Синтаксис
type-parameter-list when constraint1 [ and constraint2]
Замечания
Существует несколько различных ограничений, которые можно применить, чтобы ограничить типы, которые можно использовать в универсальном типе. В следующей таблице перечислены и описываются эти ограничения.
Ограничение | Синтаксис | Описание |
---|---|---|
Ограничение типа | тип-параметр :>тип | Указанный тип должен быть равным или производным от указанного типа или, если тип является интерфейсом, указанный тип должен реализовать интерфейс. |
Ограничение NULL | тип-параметр : null | Указанный тип должен поддерживать значение NULL. Сюда входят все типы объектов .NET, но не список F#, кортеж, функция, класс, запись или типы объединения. |
Ограничение NOT NULL | тип-параметр : не null | Указанный тип не должен поддерживать значение NULL. Это запрещает как null аннотированные типы, так и типы, которые имеют значение NULL в качестве значения представления (например, тип опций или типы, определенные с помощью атрибута AllowNullLiteral). Это универсальное ограничение разрешает типы значений, так как они никогда не могут иметь значение NULL. |
Явное ограничение члена | [(]тип-параметр [или ... или тип-параметр)] : (подпись члена) | По крайней мере один из указанных аргументов типа должен иметь член с указанной сигнатурой; не предназначено для широкого применения. Элементы должны быть явно определены в типе или части неявного расширения типа, чтобы быть допустимыми целевыми объектами для явного ограничения члена. |
Ограничение конструктора | тип-параметр : ( новое: единица —> 'a) | Указанный тип должен иметь конструктор без параметров. |
Ограничение типа значения | тип-параметр : struct | Указанный тип должен быть типом значения .NET. |
Ограничение ссылочного типа | тип-параметр: не структура | Указанный тип должен быть ссылочным типом .NET. |
Ограничение типа перечисления | тип-параметр: перечисление<базового типа> | Предоставленный тип должен быть перечисляемым и иметь указанный базовый тип; он не предназначен для широкого использования. |
Ограничение делегирования | type-parameter: делегат<кортежей-параметров типа, возвращаемого типа> | Указанный тип должен быть типом делегата, который имеет указанные аргументы и возвращаемое значение; не предназначено для общего использования. |
Ограничение сравнения | тип-параметр: сравнение | Указанный тип должен поддерживать сравнение. |
Ограничение равенства | тип-параметр : равенство | Предоставленный тип должен поддерживать равенство. |
Неуправляемые ограничения | тип-параметр : неуправляемый | Указанный тип должен быть неуправляемым типом. Неуправляемые типы — это либо определенные примитивные типы (sbyte , byte , char , nativeint , unativeint , float32 , float , int16 , uint16 , int32 , uint32 , int64 , uint64 или decimal ), типы перечисления, nativeptr<_> или неуправляемая структура, поля которых являются всеми неуправляемыми типами. |
Необходимо добавить ограничение, если код должен использовать возможность, доступную для типа ограничения, но не для типов в целом. Например, если вы используете ограничение типа для указания типа класса, можно использовать любой из методов этого класса в универсальной функции или типе.
Указание ограничений иногда требуется при явном написании параметров типа, так как без ограничения компилятор не имеет способа проверить, будут ли используемые функции доступны в любом типе, который может быть предоставлен во время выполнения для параметра типа.
Наиболее распространенные ограничения, используемые в коде F#, — это ограничения типов, которые указывают базовые классы или интерфейсы. Другие ограничения используются библиотекой F# для реализации определенных функций, таких как явное ограничение члена, которое используется для реализации перегрузки операторов для арифметических операторов или предоставляется главным образом потому, что F# поддерживает полный набор ограничений, поддерживаемых средой CLR.
Во время процесса вывода типов некоторые ограничения автоматически выводятся компилятором. Например, если в функции используется оператор +
, компилятор определяет явное ограничение члена для типов переменных, используемых в выражении.
В следующем коде показаны некоторые объявления ограничений:
// 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