특성(F#)
특성을 사용하면 프로그래밍 구문에 메타데이터를 적용할 수 있습니다.
[<target:attribute-name(arguments)>]
설명
위 구문에서 target은 선택적 요소입니다. 이를 사용하면 특성이 적용되는 프로그램 엔터티의 종류를 지정할 수 있습니다. target에 사용할 수 있는 값은 이 문서 뒷부분에 나와 있는 표를 참조하십시오.
attribute-name은 유효한 특성 형식의 이름 또는 정규화된 네임스페이스를 가리킵니다. 여기에는 특성 형식 이름에 일반적으로 사용되는 접미사인 Attribute를 포함하거나 포함하지 않을 수 있습니다. 예를 들어 이와 같은 컨텍스트에서 ObsoleteAttribute를 Obsolete로 간단히 줄일 수 있습니다.
arguments는 특성 형식의 생성자에 대한 인수입니다. 특성에 기본 생성자가 있는 경우 인수 목록과 괄호를 생략할 수 있습니다. 특성은 위치 인수와 명명된 인수를 모두 지원합니다. 위치 인수는 표시된 순서대로 사용되는 인수입니다. 명명된 인수는 특성에 public 속성이 있는 경우 사용할 수 있습니다. 인수 목록에 다음 구문을 사용하여 이를 설정할 수 있습니다.
property-name = property-value
이와 같은 속성 초기화의 순서는 아무래도 상관이 없지만 위치 인수 뒤에 속성 초기화가 와야 하는 규칙은 반드시 지켜야 합니다. 다음은 위치 인수와 속성 초기화를 사용하는 특성의 예입니다.
open System.Runtime.InteropServices
[<DllImport("kernel32", SetLastError=true)>]
extern bool CloseHandle(nativeint handle)
이 예제에서 특성은 DllImportAttribute입니다. 여기서는 축약된 형식을 사용했습니다. 첫째 인수는 위치 매개 변수이고 둘째 인수는 속성입니다.
특성은 특성이라고 하는 개체를 형식 또는 기타 프로그램 요소에 연결할 수 있는 .NET 프로그래밍 구문입니다. 특성이 적용되는 프로그램 요소를 특성 대상이라고 합니다. 특성에는 일반적으로 그 대상에 대한 메타데이터가 포함됩니다. 이와 같은 컨텍스트에서 메타데이터는 해당 필드 및 멤버 이외의 형식에 대한 임의의 데이터가 될 수 있습니다.
함수, 메서드, 어셈블리, 모듈, 형식(클래스, 레코드, 구조체, 인터페이스, 대리자, 열거형, 공용 구조체 등), 생성자, 속성, 필드, 매개 변수, 형식 매개 변수 및 반환 값 등의 프로그래밍 구문에 F#의 특성을 적용할 수 있습니다. 클래스, 식 또는 워크플로 식 내의 let 바인딩에는 특성을 사용할 수 없습니다.
일반적으로 특성 선언은 특성 대상의 선언 바로 앞에 옵니다. 다음과 같이 여러 개의 특성 선언을 함께 사용할 수 있습니다.
[<Owner("Jason Carlson")>]
[<Company("Microsoft")>]
type SomeType1 =
.NET 리플렉션을 사용하여 런타임에 특성을 쿼리할 수 있습니다.
위의 코드 예제에서와 같이 여러 특성을 개별적으로 선언할 수도 있고, 아래 나와 있는 것과 같이 여러 특성을 꺾쇠 괄호로 묶어 한꺼번에 선언할 수도 있습니다. 이때 각 특성을 구분하는 데는 세미콜론을 사용합니다.
[<Owner("Darren Parker"); Company("Microsoft")>]
type SomeType2 =
일반적으로 사용되는 특성으로는 Obsolete 특성, 보안을 고려한 특성, COM 지원을 위한 특성, 코드 소유권과 관련된 특성, 형식을 serialize할 수 있는지 여부를 나타내는 특성 등이 있습니다. 다음 예제에서는 Obsolete 특성을 사용하는 방법을 보여 줍니다.
open System
[<Obsolete("Do not use. Use newFunction instead.")>]
let obsoleteFunction x y =
x + y
let newFunction x y =
x + 2 * y
// The use of the obsolete function produces a warning.
let result1 = obsoleteFunction 10 100
let result2 = newFunction 10 100
특성 대상 assembly 및 module과 관련하여 어셈블리의 최상위 do 바인딩에 특성을 적용합니다. 다음과 같이 특성 선언에 단어 assembly 또는 module을 포함할 수 있습니다.
open System.Reflection
[<assembly:AssemblyVersionAttribute("1.0.0.0")>]
do
printfn "Executing..."
do 바인딩에 적용되는 특성에 대해 특성 대상을 생략하면 F# 컴파일러가 해당 특성에 관련이 있는 것으로 판단되는 특성 대상을 찾아내려 시도합니다. 대부분의 특성 클래스에는 해당 특성과 관련하여 지원 가능한 대상에 대한 정보를 포함하는 AttributeUsageAttribute 형식의 특성이 있습니다. 특성의 지원 대상이 함수인 것으로 AttributeUsageAttribute에 지정되어 있으면 프로그램의 주 진입점에 적용할 특성이 선택됩니다. 특성의 지원 대상이 어셈블리인 것으로 AttributeUsageAttribute에 지정되어 있으면 어셈블리에 적용할 특성이 컴파일러를 통해 선택됩니다. 대부분의 특성은 함수와 어셈블리 중 하나에만 적용되지만 경우에 따라서는 둘 다에 적용되는 특성도 있습니다. 이 경우 프로그램의 주 함수에 적용할 특성이 선택됩니다. 특성 대상을 명시적으로 지정한 경우에는 지정한 대상에 특성이 적용됩니다.
일반적으로 특성 대상을 명시적으로 지정할 필요는 없지만 아래 표를 참조하여 특성의 target에 사용할 수 있는 유효한 값과 그 용례를 알고 있으면 작업에 도움이 됩니다.
특성 대상 |
예제 |
---|---|
assembly |
[<assembly: AssemblyVersionAttribute("1.0.0.0")>] |
return |
let function1 x : [<return: Obsolete>] int = x + 1 |
필드 |
[<field: DefaultValue>] val mutable x: int |
속성 |
[<property: Obsolete>] this.MyProperty = x |
param |
member this.MyMethod([<param: Out>] x : ref<int>) = x := 10 |
type |
[<type: StructLayout(Sequential)>] type MyStruct = struct x : byte y : int end |