次の方法で共有


制約 (F#)

このトピックでは、ジェネリック型パラメーターに適用できる制約について説明します。この制約を適用して、ジェネリック型またはジェネリック関数の型引数の要件を指定します。

type-parameter-list when constraint1 [ and constraint2]

解説

ジェネリック型で使用できる型は、数種類の制約を適用して制限できます。 次の表にこれらの制約の一覧を示し、それぞれの内容について説明します。

制約

構文

説明

型制約

type-parameter :> type

型パラメーターは、指定した型と同じであるか、指定した型から派生している必要があります。指定した型がインターフェイスの場合は、型パラメーターにインターフェイスを実装する必要があります。

null 制約

type-parameter : null

型パラメーターは、null リテラルをサポートする必要があります。 これには、F# のリスト型、タプル型、関数型、クラス型、レコード型、または共用体型以外のすべての .NET オブジェクト型が含まれます。

明示的なメンバーの制約

[出力] ([type-parameter または… または type-parameter) ] : (member-signature)

少なくとも 1 つの型パラメーターの引数に、指定したシグネチャを持つメンバーが含まれている必要があります。これは、一般的に使用するための制約ではありません。

コンストラクター制約

type-parameter : ( new : unit -> 'a )

型パラメーターには既定のコンストラクターが必要です。

値型の制約

: struct

型パラメーターは、.NET の値型である必要があります。

参照型の制約

: not struct

型パラメーターは、.NET の参照型である必要があります。

列挙型の制約

: enum<underlying-type>

型パラメーターは、指定した基になる型を持つ列挙型である必要があります。これは、一般的に使用するための制約ではありません。

デリゲートの制約

: delegate<tuple-parameter-type, return-type>

型パラメーターは、指定した引数と戻り値を持つデリゲート型である必要があります。これは、一般的に使用するための制約ではありません。

比較の制約

: comparison

型パラメーターは、比較をサポートする必要があります。

等価性の制約

: equality

型パラメーターは、等価性をサポートする必要があります。

アンマネージの制約

: unmanaged

型パラメーターは、アンマネージ型である必要があります。 アンマネージ型は、特定のプリミティブ型 (sbyte、byte、char、nativeint、unativeint、float32、float、int16、uint16、int32、uint32、int64、uint64、または decimal)、列挙型、nativeptr<_>、またはすべてのフィールドがアンマネージ型である非ジェネリック構造体のいずれかです。

制約型では使用できるが、一般的な型では使用できない機能をコードで使用する必要がある場合には、制約を追加する必要があります。 たとえば、型制約を使用してクラス型を指定すると、そのクラスのいずれかのメソッドをジェネリック関数またはジェネリック型で使用することができます。

型パラメーターを明示的に記述するときは、制約の指定が必要になる場合があります。制約を指定しないと、使用している機能が実行時に型パラメーターとして指定される可能性がある型に対応しているかどうかをコンパイラが判断できないためです。

F# のコードで最もよく使用される制約は、基本クラスやインターフェイスを指定する型制約です。 その他の制約は、算術演算子に対する演算子のオーバーロードの実装に使用される明示的なメンバーの制約など、特定の機能を実装するための F# ライブラリで使用されるか、提供されるかのいずれかです。その主な理由は、F# が共通言語ランタイムでサポートされているすべての制約をサポートしているためです。

型推論プロセスで、コンパイラによって自動的に推論される制約もあります。 たとえば、関数内で + 演算子を使用する場合、式で使用されている変数の型に対する明示的なメンバーの制約がコンパイラによって推論されます。

次のコードは、制約の申告について説明します。

// 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 static member
type Class4<'T when 'T : (static member staticMethod1 : unit -> 'T) > =
    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

参照

関連項目

ジェネリック (F#)

制約 (F#)