共用方式為


委派 (F#)

委派會將函式呼叫表示為物件。在 F# 中,通常應該使用函式值來將函式表示為優先使用的值。不過,委派是用於 .NET Framework 中,因此與必須使用委派的 API 交互操作時就需要委派。編寫設計為從其他 .NET Framework 語言使用的程式庫時,可能也會使用它們。

type delegate-typename = delegate of type1 -> type2

備註

在先前的語法中,type1 表示引數型別,而 type2 則表示傳回型別。由 type1 表示的引數型別會自動局部調用。這表示,如果目標函式的引數為局部調用,則針對此型別使用 Tuple,並針對已經是 Tuple 形式的引數,使用加上括號的 Tuple。自動局部調用會移除一組括號,保留符合目標方法的 Tuple 引數。請參閱程式碼範例,取得每個案例應使用的語法。

委派可以附加至 F# 函式值,以及靜態方法或執行個體方法。F# 函式值可以當做引數直接傳遞給委派建構函式。若是靜態方法,您必須使用類別名稱和方法來建構委派;若是執行個體方法,您必須在一個引數中提供物件執行個體和方法。在這兩種情況下,都會使用成員存取運算子 (.)。

委派型別上的 Invoke 方法會呼叫封裝的函式。另外,您也可以透過參考 Invoke 方法名稱 (不加括號),將委派當做函式值來傳遞。

在下列程式碼範例中,會示範建立表示類別中各種方法之委派的語法。根據方法為靜態方法或執行個體方法,以及方法的引數為 Tuple 形式或局部調用形式,宣告及指派委派的語法稍有不同。

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"|]

請參閱

概念

參數和引數 (F#)

其他資源

F# 語言參考

事件 (F#)