次の方法で共有


制約

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

構文

type-parameter-list when constraint1 [ and constraint2]

Remarks

ジェネリック型で使用できる型を制限するために適用できる制約は複数あります。 次の表に、これらの制約の一覧と説明を示します。

制約 構文 説明
型制約 型パラメーター :> 指定された型は、指定された型と等しいか、指定された型から派生している必要があります。または、型がインターフェイスの場合は、指定された型がインターフェイスを実装する必要があります。
Null 制約 type-parameter : null 指定された型は null 値をサポートする必要があります。 これには、F# リスト、タプル、関数、クラス、レコード、または共用体の型ではなく、すべての .NET オブジェクト型が含まれます。
Not Null 制約 型パラメーターの: null ではありません 指定された型は null 値をサポートできません。 これにより、null 注釈付き型と、その表現値として null を持つ型 (オプションの型や AllowNullLiteral 属性で定義された型など) の両方が禁止されます。 このジェネリック制約では、値型を許容します。値型は null になることはないからです。
明示的なメンバー制約 [(]型パラメーター [または 型パラメーター)] : (メンバー署名) 指定された型引数の少なくとも 1 つに、指定されたシグネチャを持つメンバーが必要です。一般的な使用を意図していません。 明示的メンバー制約の有効なターゲットにするには、型または暗黙的な型拡張の一部でメンバーを明示的に定義する必要があります。
コンストラクター制約 type-parameter : ( new : unit -> 'a ) 指定された型には、パラメーターなしのコンストラクターが必要です。
値型制約 type-parameter : struct 指定する型は .NET 値型である必要があります。
参照型制約 型パラメーター: は構造体ではありません 指定する型は、.NET 参照型である必要があります。
列挙型の制約 type-parameter : enum<underlying-type> 指定された型は、指定された基になる型を持つ列挙型である必要があります。一般的な使用を意図していません。
デリゲート制約 型パラメーター: デリゲート<タプルパラメーター型、戻り値型 > 指定された型は、指定された引数と戻り値を持つデリゲート型である必要があります。一般的な使用を意図していません。
比較制約 type-parameter : comparison 指定された型は比較をサポートする必要があります。
等値制約 型パラメーター : 等価 指定された型は等値をサポートする必要があります。
管理されていない制約 型パラメーター: アンマネージド 指定する型はアンマネージ型である必要があります。 アンマネージド型は、特定のプリミティブ型 (sbytebytecharnativeintunativeintfloat32floatint16uint16int32uint32int64uint64、または 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

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

関連項目