共用方式為


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# 中的運算子可以透過兩種方式使用,作為運算子文字本身,或代表已編譯表單的符號。 運算子的 nameof 將在來源中宣告運算子時,產生該運算子的名稱。 若要取得編譯的名稱,請使用來源中的編譯名稱:

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

泛型的 Nameof

您也可以採用泛型型別參數的名稱,但語法不同:

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

nameof<'TGeneric> 將採用來源中所定義的符號名稱,而不會採用已在呼叫網站上取代的類型名稱。

語法不同的原因是要與其他 F# 內建運算子 (例如 typeof<>typedefof<>) 保持一致。 這讓 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