2010-08-01 31 views
5

Stavo cercando di usare Rhino Mocks con codice F #, e il seguente codice era una problematica:È possibile definire un metodo di estensione generico in F #?

let service = MockRepository.GenerateMock<IMyService>() 
service.Stub(s => s.Name).Return("Service"); 

Questa è stata una sorpresa, dal momento che Stub non fa parte della interfaccia IMyService, si tratta di un metodo di estensione C# che Rhino Mocks definisce.

codice

slighltly modificata funziona:

let service = MockRepository.GenerateMock<IMyService>() 
RhinoMocksExtensions.Stub<IMyService, string>(service, fun s -> s.Name).Return("Service"); 

Tuttavia, sarebbe bello per definire un metodo di estensione in F #, ma poi sarà un metodo di estensione generica con parametri che avrebbe preso una tupla. Stavo provando la sintassi dei varios, ma senza fortuna. Non ho trovato informazioni se questo è attualmente supportato in F # o no. Se qualcuno sa, per favore fatemi sapere.

risposta

3

Se ho capito bene la tua domanda, la risposta è no. Section 8.12.1 of the spec (importato C# Estensioni Utenti) include questo testo:

C# -defined elementi di estensione sono resi disposizione di codice F # in ambienti in cui il gruppo C# -authored è di riferimento e una dichiarazione aperta di corrispondente namespace è nell'effetto . Tuttavia, applicano alcune limitazioni, in particolare i membri # estensione

  • C la cui “questo” parametro è un tipo di variabile non sono messi a disposizione codice F # in questa versione di F #

  • elementi di estensione C# la cui “questo” parametro è un tipo di matrice non sono messi a disposizione codice F # in questa versione di F #

Questo spiega perché alcuni metodi di estensione da C# funzioneranno (ad es. quelli in System.Linq), mentre quello che si sta tentando di utilizzare non lo farà.

Inoltre, i metodi di estensione F # nativi possono essere definiti come se fossero posizionati su definizioni di tipo reali. In particolare, non è possibile definire un metodo di estensione F # su un tipo generico chiuso (ad esempio IEnumerable<string>) né è possibile definire un metodo di estensione su una variabile di tipo generica.

+0

Grazie per la risposta! –

4

Come accennato in KVB, non è possibile in F # 2.0. In questo caso particolare mi piacerebbe avvolgo Rhino.Mocks interfaccia fluida per renderlo più idiomatica in F #, ad esempio:

let mstub f target = 
    RhinoMocksExtensions.Stub(target, Function(f)) 

let mreturn value (options: IMethodOptions<'a>) = 
    options.Return value 

let service = MockRepository.GenerateMock<IComparer>() 
service |> mstub (fun s -> s.Compare(1,2)) |> mreturn 1 |> ignore 

What's fluent in one language is not necessarily fluent in another. (spiacente per la spina, ma credo davvero che sia rilevante qui)

+0

Marurcio, Grazie per la spiegazione. Sì, sono arrivato alla stessa conclusione che tali estensioni che sono abbastanza utili in C# non porterebbero così tanto valore a F #, e ci sono altri (e migliori) modi di esprimerlo in F #. –

Problemi correlati