2010-08-01 10 views
5

yo estaba tratando de utilizar burla de Rhino con F # código y el código siguiente era una problemática:¿Es posible definir un método de extensión genérico en F #?

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

Esto no fue una sorpresa, ya que del trozo no es parte de la interfaz IMyService, es un método de extensión C# que burla de Rhino define.

código

Slighltly modificado funciona:

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

Sin embargo, sería bueno definir un método de extensión en Fa #, pero entonces será un método de extensión genérica con parámetros que tomaría una tupla. Estaba intentando sintaxis varios pero sin suerte. No encontré información si esto actualmente es compatible con F # o no. Si alguien sabe, por favor hágamelo saber.

Respuesta

3

Si entiendo su pregunta correctamente, la respuesta es no. Section 8.12.1 of the spec (importado C# Extensiones Miembros) incluye este texto:

C# -definido miembros de extensión están hechos disponible para F # código en entornos donde el conjunto C# autoría de éstos es referencia y una declaración abierta de el espacio de nombres correspondiente está en el efecto . Sin embargo, se aplican algunas limitaciones, sobre todo

  • C miembros # extensión cuyo “este” parámetro es un tipo de variable no son puesto a disposición de F # código en esta versión de F #

  • miembros de extensión de C# cuyo “este” parámetro es un tipo de matriz no se a disposición de F # código en esta versión de F #

Esto explica por qué algunos métodos de extensión de C# funcionarán (p. aquellos en System.Linq), mientras que el que está intentando usar no lo hará.

Además, los métodos nativos de extensión F # solo se pueden definir como si estuvieran colocados en definiciones de tipo reales. En particular, no puede definir un método de extensión F # en un tipo genérico cerrado (por ejemplo, IEnumerable<string>) ni puede definir un método de extensión en una variable de tipo genérica.

+0

Gracias por ¡la respuesta! –

4

Como se mencionó en kvb, no es posible en F # 2.0. En este caso particular, me envuelvo Rhino.Mocks interfaz fluida para que sea más idiomática en Fa #, por ejemplo:

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. (lo siento por el tapón, pero realmente creo que es relevante aquí)

+0

Marurcio, Gracias por la explicación. Sí, también llegué a la misma conclusión de que tales extensiones que son bastante útiles en C# no aportarían tanto valor a F #, y hay otras (y mejores) formas de expresar esto en F #. –

Cuestiones relacionadas