Domanda

In particolare quali sono le caratteristiche (se presenti) che i delegati hanno che le funzioni come valori di prima classe in F # non hanno; e quali sono le caratteristiche che funzioni come valori di prima classe hanno (se presente) che i delegati in C # non hanno?

È stato utile?

Soluzione

I delegati e F # "valori della funzione di prima classe" sono molto diverse.

I delegati sono un meccanismo del CLR, un tipo-safe involucro intorno coppie + oggetto funzione-puntatore (per metodi di istanza, il this puntatore viene catturato insieme all'indirizzo metodo).

I valori # funzione f d'altra parte, sono l'attuazione di una classe astratta FSharpFunc<,> (ha usato per essere chiamato FastFunc<,> prima del rilascio ufficiale di F #). Invocazione avviene tramite metodi virtuali ordinari, che è molto più veloce di delegato invocazione. Questa è la ragione della F # -Team non ha utilizzato i delegati, in primo luogo.

Quindi, se si può "implementare" funziona come valori di prima classe attraverso le classi astratte / metodi virtuali, perché i delegati aggiungere Microsoft?

  • Non c'erano alternative in .NET 1.0 / 1.1, non c'erano farmaci generici, quindi si doveva definire un nuovo tipo delegato (= "tipo di funzione") per ogni firma della funzione che si voleva utilizzare .
  • (No, solo utilizzando interfacce come in Java non conta. :-P)

Ok, ma abbiamo Generics dal .NET 2.0, perché abbiamo ancora delegati? Perché non possiamo semplicemente usare Func<,> e Action<> per tutto?

  • Compatibilità
  • multicast delegati I delegati possono essere concatenati insieme per formare nuovi delegati. Questo meccanismo viene utilizzato per implementare gli eventi in VB.NET e C #. Dietro le quinte, un evento è in realtà solo un singolo campo delegato. Utilizzando il += sintassi essenzialmente aggiungere il gestore di eventi-delegato alla catena dei delegati del settore eventi.

A parte gli eventi, c'è una ragione per usare delegati nel corso FSharpFunc<,>

Sì, uno: Ogni implementazione di FSharpFunc<,>, che include lambda-espressioni *, è una nuova classe. E in NET classi sono codificati nei metadati della compilato assemblaggio. I delegati d'altra parte non richiedono metadati aggiuntivi. Il delegato tipo fare, ma creare un'istanza di questi tipi delegato è libera in termini di metadati.

Ma aspettate, non sono C # lambda-espressioni / i metodi anonimi anche implementati come classi nascoste?

Si, C # lambda prendere il peggio dei due mondi ^^

Altri suggerimenti

Volevo solo aggiungere che questa dichiarazione di SealedSun non è vero:

  

Invocazione avviene via ordinaria   metodi virtuali, che è molto più veloce   di delegato invocazione. Questo è il   motivo il F # -Team non ha utilizzato   i delegati, in primo luogo.

F # funzioni non sono più veloci quindi delegano invocazione, forse era il caso di nuovo in .NET 1.0, ma ora un'invocazione giorni delegato e metodi virtuali invocando sono più o meno in pari.

invocando anche F funzioni # che non può essere vincolata staticamente dal compilatore è molto lento rispetto ad invocare un delegato.

open System
open System.Diagnostics

let time name f = 
  let sw = new Stopwatch()
  sw.Start()
  f()
  sw.Stop()
  printfn "%s: %dms" name sw.ElapsedMilliseconds

time "delegate call" (
  fun () ->
    let f = 
      new Func<int, int, int>(
        fun i1 i2 -> 
          let y = i1 + i2
          let x = y + i1
          let z = x + y + i2
          z + x + y + i1
      )

    let mutable r = 0
    for i = 0 to 10000000 do
      r <- f.Invoke(i, i)
)

let f i1 i2 = 
  let y = i1 + i2
  let x = y + i1
  let z = x + y + i2
  z + x + y + i1

time "fsharp func (static bound)" (
  fun () ->
    let mutable r = 0
    for i = 0 to 10000000 do
      r <- f i i
)

let make f =
  let mutable r = 0
  for i = 0 to 10000000 do
    r <- f i i

time "fsharp func (dynamic bound)" (
  fun () -> make f
)

Console.ReadLine() |> ignore

produce i seguenti risultati sul mio computer

delegate call: 65ms
fsharp func (staticly linked): 4ms
fsharp func (dynamic invoke): 356ms
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top