대리자(F#)
대리자는 함수 호출을 개체로 표현합니다.F#에서는 함수를 고급 값으로 표현하는 데 일반적으로 함수 값을 사용해야 합니다. 그러나 .NET Framework에는 대리자가 사용되므로 대리자를 필요로 하는 API와 상호 작용할 때는 대리자가 있어야 합니다.다른 .NET Framework 언어에서 사용할 목적으로 디자인된 라이브러리를 작성할 때도 대리자를 사용할 수 있습니다.
type delegate-typename = delegate of type1 -> type2
설명
위 구문에서 type1은 하나 이상의 인수 형식을 나타내고 type2는 반환 형식을 나타냅니다.type1로 표현되는 인수 형식은 자동 변환됩니다.따라서 대상 함수의 인수가 변환되는 경우 이 형식에 대해 튜플을 사용해야 하고 튜플에 이미 포함되어 있는 인수에 대해서는 괄호로 묶은 튜플을 사용해야 합니다.자동 변환 과정에서 괄호 쌍이 제거되고 대상 메서드에 일치하는 튜플 인수가 남겨집니다.각각의 경우에 사용해야 할 구문에 대해서는 코드 예제를 참조하십시오.
대리자는 F# 함수 값 및 정적 또는 인스턴스 메서드에 연결될 수 있습니다.F# 함수 값은 대리자 생성자에 인수로 직접 전달할 수 있습니다.정적 메서드의 경우 클래스와 메서드의 이름을 사용하여 대리자를 만듭니다.인스턴스 메서드의 경우 개체 인스턴스와 메서드를 인수 하나로 제공합니다.두 경우 모두 멤버 액세스 연산자(.)가 사용됩니다.
대리자 형식의 Invoke 메서드는 캡슐화된 함수를 호출합니다.또한 대리자는 호출 메서드 이름을 괄호 없이 참조하여 함수 값으로 전달할 수도 있습니다.
다음 코드에서는 클래스의 다양한 메서드를 나타내는 대리자를 만들기 위한 구문을 보여 줍니다.메서드가 정적 메서드인지 인스턴스 메서드인지 여부와 인수가 튜플 형식인지 변환 형식인지 여부에 따라 대리자를 선언하고 할당하는 구문에 약간의 차이가 있습니다.
type Test1() =
static member add(a : int, b : int) =
a + b
static member add2 (a : int) (b : int) =
a + b
member x.Add(a : int, b : int) =
a + b
member x.Add2 (a : int) (b : int) =
a + b
// Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int * int) -> int
// Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int
let InvokeDelegate1 (dlg : Delegate1) (a : int) (b: int) =
dlg.Invoke(a, b)
let InvokeDelegate2 (dlg : Delegate2) (a : int) (b: int) =
dlg.Invoke(a, b)
// For static methods, use the class name, the dot operator, and the
// name of the static method.
let del1 : Delegate1 = new Delegate1( Test1.add )
let del2 : Delegate2 = new Delegate2( Test1.add2 )
let testObject = Test1()
// For instance methods, use the instance value name, the dot operator, and the instance method name.
let del3 : Delegate1 = new Delegate1( testObject.Add )
let del4 : Delegate2 = new Delegate2( testObject.Add2 )
for (a, b) in [ (100, 200); (10, 20) ] do
printfn "%d + %d = %d" a b (InvokeDelegate1 del1 a b)
printfn "%d + %d = %d" a b (InvokeDelegate2 del2 a b)
printfn "%d + %d = %d" a b (InvokeDelegate1 del3 a b)
printfn "%d + %d = %d" a b (InvokeDelegate2 del4 a b)
다음 코드에서는 대리자 사용법을 몇 가지 보여 줍니다.
type Delegate1 = delegate of int * char -> string
let replicate n c = String.replicate n (string c)
// An F# function value constructed from an unapplied let-bound function
let function1 = replicate
// A delegate object constructed from an F# function value
let delObject = new Delegate1(function1)
// An F# function value constructed from an unapplied .NET member
let functionValue = delObject.Invoke
List.map (fun c -> functionValue(5,c)) ['a'; 'b'; 'c']
|> List.iter (printfn "%s")
// Or if you want to get back the same curried signature
let replicate' n c = delObject.Invoke(n,c)
// You can pass a lambda expression as an argument to a function expecting a compatible delegate type
// System.Array.ConvertAll takes an array and a converter delegate that transforms an element from
// one type to another according to a specified function.
let stringArray = System.Array.ConvertAll([|'a';'b'|], fun c -> replicate' 3 c)
printfn "%A" stringArray
위 코드 예제의 출력은 다음과 같습니다.
aaaaa
bbbbb
ccccc
[|"aaa"; "bbb"|]