형식 확장(F#)
형식 확장을 사용하면 이전에 정의한 개체 형식에 새 멤버를 추가할 수 있습니다.
// Intrinsic extension.
type typename with
member self-identifier.member-name =
body
...
[ end ]
// Optional extension.
type typename with
member self-identifier.member-name =
body
...
[ end ]
설명
형식 확장에는 두 가지 형태가 있으며 그 각각은 구문과 동작에 약간의 차이가 있습니다.기본 확장은 확장하려는 형식과 같은 네임스페이스나 모듈, 같은 소스 파일, 같은 어셈블리(DLL 또는 실행 파일)에 표시되는 확장입니다.선택적 확장은 확장하려는 형식의 원래 모듈, 네임스페이스 또는 어셈블리 외부에 표시되는 확장입니다.리플렉션을 통해 형식을 조사하는 경우 기본 확장은 형식에 표시되지만 선택적 확장은 표시되지 않습니다.선택적 확장은 모듈에 있어야 하며 확장을 포함하는 모듈을 연 경우에만 범위에 포함됩니다.
위 구문에서 typename은 확장할 형식을 나타냅니다.액세스 가능한 형식이면 무엇이든 확장할 수 있지만 형식 이름은 형식 약어가 아니라 실제 형식 이름이어야 합니다.형식 확장 하나로 여러 멤버를 정의할 수 있습니다.self-identifier는 일반적인 멤버의 경우와 마찬가지로 호출할 개체의 인스턴스를 나타냅니다.
간단한 구문에서는 end 키워드를 생략할 수 있습니다.
형식 확장에 정의되는 멤버는 클래스 형식의 다른 멤버와 같은 방식으로 사용할 수 있습니다.다른 멤버와 마찬가지로 이들 멤버는 정적 멤버이거나 인스턴스 멤버일 수 있습니다.이러한 메서드를 확장 메서드라 하고, 속성을 확장 속성이라 하는 식입니다.선택적 확장 멤버는 정적 멤버로 컴파일되며 이 멤버에는 개체 인스턴스가 첫째 매개 변수 지위를 갖고 암시적으로 전달됩니다.그러나, 선언 방법에 따라 인스턴스 멤버 또는 정적 멤버인 것처럼 동작합니다.암시적 확장 멤버는 형식의 멤버로 포함되며 아무런 제한 없이 사용할 수 있습니다.
확장 메서드는 가상 메서드나 추상 메서드가 될 수 없습니다.이러한 메서드에서 같은 이름의 다른 메서드를 오버로드할 수 있지만 오버로드로 인해 호출이 모호하게 되면 컴파일러에서 확장되지 않은 메서드에 더 높은 우선 순위를 부여합니다.
한 형식에 대해 여러 개의 기본 형식 확장이 있는 경우에는 각 멤버가 저마다 고유해야 합니다.선택적 형식 확장의 경우에는 동일한 형식에 대한 서로 다른 형식 확장의 멤버 이름이 같아도 됩니다.모호성으로 인한 오류는 동일한 멤버 이름을 정의하는 서로 다른 두 범위가 클라이언트 코드를 통해 열리는 경우에만 발생합니다.
다음 예제에서 모듈의 형식에는 기본 형식 확장이 있습니다.모듈 외부에 있는 클라이언트 코드에는 형식 확장이 어느 모로 보나 형식의 일반적인 멤버처럼 표시됩니다.
module MyModule1 =
// Define a type.
type MyClass() =
member this.F() = 100
// Define type extension.
type MyClass with
member this.G() = 200
module MyModule2 =
let function1 (obj1: MyModule1.MyClass) =
// Call an ordinary method.
printfn "%d" (obj1.F())
// Call the extension method.
printfn "%d" (obj1.G())
기본 형식 확장을 사용하여 형식의 정의를 여러 섹션으로 나눌 수 있습니다.이 방법은 컴파일러를 통해 생성된 코드와 사용자가 작성한 코드를 따로 구분하여 관리하거나 여러 사람이 만든 코드 또는 각기 다른 기능에 관련된 코드를 함께 묶어 그룹으로 관리하려는 경우 등과 같이 크기가 큰 형식 정의를 관리하는 데 유용할 수 있습니다.
다음 예제에서 선택적 형식 확장은 정적 멤버 Parse를 호출하는 확장 메서드 FromString을 사용하여 System.Int32 형식을 확장합니다.testFromString 메서드를 보면 새 멤버를 호출하는 방법이 다른 임의의 인스턴스 멤버를 호출하는 방법과 같다는 것을 알 수 있습니다.
// Define a new member method FromString on the type Int32.
type System.Int32 with
member this.FromString( s : string ) =
System.Int32.Parse(s)
let testFromString str =
let mutable i = 0
// Use the extension method.
i <- i.FromString(str)
printfn "%d" i
testFromString "500"
새 인스턴스 멤버는 IntelliSense에 Int32 형식의 다른 모든 메서드와 마찬가지로 표시되지만 이 멤버가 표시되기 위해서는 확장을 포함하는 모듈이 열려 있거나 기타 방식으로 범위에 포함되어 있어야 합니다.