2010-08-01 5 views
5

Je tentais d'utiliser Rhino Mocks avec code F #, et le code suivant était une problématique:Est-il possible de définir une méthode d'extension générique en F #?

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

Ce ne fut pas une surprise, puisque Stub ne fait pas partie de l'interface IMyService, il est une méthode d'extension C# Rhino Mocks définit.

code modifié slighltly fonctionne:

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

Cependant, il serait agréable de définir une méthode d'extension en F #, mais ce sera une méthode d'extension générique paramétrés qui prendrait un tuple. J'essayais la syntaxe de varios mais sans aucune chance. Je n'ai pas trouvé d'information si ceci est actuellement supporté en F # ou pas. Si quelqu'un sait, s'il vous plaît faites le moi savoir.

Répondre

3

Si je comprends bien votre question, la réponse est non. Section 8.12.1 of the spec (Importé C# Extensions membres) comprend ce texte:

C# -defined éléments d'extension sont en disponibles à F # code dans des environnements où l'assemblage C# -authored est référencé et une déclaration ouverte de l'espace de noms correspondant est en effet. Cependant, certaines limites s'appliquent, notamment

  • C# des éléments d'extension dont « ce » paramètre est un type de variable ne sont pas mis à la disposition F # code dans cette version de F #

  • C# des éléments d'extension dont « ce » paramètre est un type de tableau ne sont pas mis à la disposition F # code dans cette version de F #

Ceci explique pourquoi certaines méthodes d'extension de C# fonctionneront (par ex. ceux dans System.Linq), tandis que celui que vous essayez d'utiliser ne le sera pas.

Par ailleurs, les méthodes d'extension F # natives ne peuvent être définies que si elles ont été placées sur des définitions de type réelles. En particulier, vous ne pouvez pas définir une méthode d'extension F # sur un type générique fermé (par exemple IEnumerable<string>) ni définir une méthode d'extension sur une variable de type générique.

+0

Merci pour la réponse! –

4

Comme kvb mentionné, ce n'est pas possible dans F # 2.0. Dans ce cas particulier je conclurai Rhino.Mocks interface fluide pour le rendre plus idiomatiques en F #, par exemple:

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. (désolé pour le bouchon, mais je pense vraiment qu'il est pertinent ici)

+0

Marurcio, Merci pour l'explication. Oui, je suis également arrivé à la même conclusion que de telles extensions qui sont très utiles en C# n'apporteraient pas autant de valeur à F #, et il existe d'autres (et meilleures) façons d'exprimer cela en F #. –