Nameof

nameof 式では、ソース内のほぼすべての F# コンストラクトのソースの名前と一致する文字列定数を生成します。

構文

nameof symbol
nameof<'TGeneric>

解説

nameof は、渡されたシンボルを解決し、ソース コード内で宣言されたかのようにシンボルの名前を生成することによって機能します。 これは、ログ記録などのさまざまなシナリオで役立ち、ソース コードの変更からログ記録が保護されます。

let months =
    [
        "January"; "February"; "March"; "April";
        "May"; "June"; "July"; "August"; "September";
        "October"; "November"; "December"
    ]

let lookupMonth month =
    if (month > 12 || month < 1) then
        invalidArg (nameof month) ($"Value passed in was %d{month}.")

    months[month-1]

printfn "%s" (lookupMonth 12)
printfn "%s" (lookupMonth 1)
printfn "%s" (lookupMonth 13)

最後の行では例外がスローされ、エラー メッセージに "month" と表示されます。

ほぼすべての F# コンストラクトの名前を取得できます。

module M =
    let f x = nameof x

printfn $"{(M.f 12)}"
printfn $"{(nameof M)}"
printfn $"{(nameof M.f)}"

nameof はファーストクラス関数ではなく、そのようには使用できません。 つまり、これを部分的に適用することはできず、F# パイプライン演算子を使用して値を送信することはできません。

演算子上の nameof

F# の演算子は、演算子テキスト自体として、またはコンパイルされたフォームを表すシンボルの 2 つの方法で使用できます。 演算子上の nameof では、ソースで宣言されたかのように演算子の名前を生成します。 コンパイルされた名前を取得するには、ソース内でコンパイル済みの名前を使用します。

nameof(+) // "+"
nameof op_Addition // "op_Addition"

ジェネリック上の nameof

ジェネリック型パラメーターの名前にすることもできますが、構文は異なります。

let f<'a> () = nameof<'a>
f() // "a"

nameof<'TGeneric> では、呼び出しサイトで置き換えられた型の名前ではなく、ソース内で定義されているシンボルの名前を受け取ります。

構文が異なる理由は、typeof<>typedefof<> などの他の F# 組み込み演算子と一致させるためです。 これにより、ジェネリック型やソース内の他のあらゆるものに対して作用する演算子と F# の一貫性が確保されます。

パターン マッチ内の nameof

nameof パターン を使用すると、パターン マッチ式でこのように nameof を使用できます。

let f (str: string) =
    match str with
    | nameof str -> "It's 'str'!"
    | _ -> "It is not 'str'!"

f "str" // matches
f "asdf" // does not match

インスタンス メンバーでの nameof

F# では、nameof を使用してインスタンス メンバーの名前を抽出するために、インスタンスが必要です。 インスタンスを簡単に使用できない場合は、Unchecked.defaultof を使用して取得できます。

type MyRecord = { MyField: int }
type MyClass() =
    member _.MyProperty = ()
    member _.MyMethod () = ()

nameof Unchecked.defaultof<MyRecord>.MyField   // MyField
nameof Unchecked.defaultof<MyClass>.MyProperty // MyProperty
nameof Unchecked.defaultof<MyClass>.MyMethod   // MyMethod