null制約の概要
F#のジェネリックパラメータに対して、「nullリテラルをサポートしていること」を強制することができます。これをnull制約と言います。.NETオブジェクト型はこれをサポートしていますが、F#リスト型・タプル型・関数・クラス・構造体・レコード型・判別共用体型はサポートされていません。そのため、基本的にはF#の型をnull制約があるジェネリック型の型パラメータに指定することはできませんので、覚えておくと良いでしょう。
サンプルでみるnull制約
次の例では、null制約の簡単な利用方法を紹介しています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ========================================================= | |
// null制約のサンプル | |
// ========================================================= | |
// 'T型は, nullリテラルをサポートしている必要があります. | |
type ClassA<'T when 'T: null> () = class | |
end | |
// --------------------------------------------------------- | |
// ただのF#クラス型 | |
type SampleClass () = class | |
end | |
// ただのF#構造体型 | |
type SampleStruct = struct | |
end | |
// ただのF#レコード型 | |
type SampleRecord = { X:int } | |
// SampleClassは, F#のクラス型であるため, | |
// ClassAジェネリッククラスの型パラメータに指定することができません. | |
let c1 = new ClassA<SampleClass> () // エラー | |
// SampleStructは, F#の構造体型であるため, | |
// ClassAジェネリッククラスの型パラメータに指定することができません. | |
let c2 = new ClassA<SampleStruct> () // エラー | |
// SampleRecordは, F#のレコード型であるため, | |
// ClassAジェネリッククラスの型パラメータに指定することができません. | |
let c3 = new ClassA<SampleRecord> () // エラー | |
// string(= System.String)は, .NETオブジェクト型のため, | |
// ClassAジェネリッククラスの型パラメータに指定することが可能です. | |
let c4 = new ClassA<string> () // OK | |
// --------------------------------------------------------- | |
// 明示的にSystem.Objectクラスを継承したF#クラス型 | |
type SampleClass2 () = class | |
inherit System.Object () | |
end | |
// 明示的にSystem.Objectを継承していても, null制約を突破することはできません. | |
let c5 = new ClassA<SampleClass2> () // エラー | |