다음을 통해 공유


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)

마지막 줄은 예외를 throw하고 "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> 는 호출 사이트에서 대체된 형식의 이름이 아니라 원본에 정의된 기호의 이름을 사용합니다.

구문이 다른 이유는 다음과 같은 typeof<>typedefof<>다른 F# 내장 연산자와 일치하기 때문입니다. 따라서 F#은 제네릭 형식 및 원본의 다른 모든 항목에 대해 작동하는 연산자와 일치합니다.

패턴 일치의 Nameof

패턴을nameof 사용하면 패턴 일치 식에 사용할 nameof 수 있습니다. 이 기능은 코드의 기호 이름과 문자열 값을 일치시켜 리팩터링할 때 컴파일 시간 안전성 및 자동 업데이트를 제공하는 경우에 특히 유용합니다.

실제 예제는 문자열 값이 형식 또는 대/소문자 이름을 나타내는 이벤트 또는 메시지를 역직렬화하는 것입니다.

type EventType =
    | OrderCreated
    | OrderShipped
    | OrderDelivered

let handleEvent eventName data =
    match eventName with
    | nameof OrderCreated -> printfn "Processing order creation: %s" data
    | nameof OrderShipped -> printfn "Processing order shipment: %s" data
    | nameof OrderDelivered -> printfn "Processing order delivery: %s" data
    | _ -> printfn "Unknown event type: %s" eventName

handleEvent "OrderCreated" "Order #123" // matches first case

다음과 같은 문자열 리터럴 대신 사용하면 nameof 다음과 같은 "OrderCreated" 몇 가지 이점이 있습니다.

  • 구분된 공용 구조체 사례의 이름을 바꾸면 패턴이 자동으로 업데이트됩니다.
  • 컴파일러는 기호가 있는지 확인하여 오타를 방지합니다.
  • 코드는 리팩터링하는 동안 일관성을 유지합니다.

매개 변수와 함께 사용할 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