2010-08-01 21 views
5

Ich habe versucht, Rhino Mocks mit F # Code, und der folgende Code war ein problematischer zu verwenden:Kann eine generische Erweiterungsmethode in F # definiert werden?

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

Das war keine Überraschung, da Stub nicht Teil IMyService Schnittstelle ist, es ist eine Erweiterung C# Methode, die Rhino Mocks definiert.

Slighltly modifizierte Code funktioniert:

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

Allerdings wäre es schön, eine Erweiterungsmethode in F # zu definieren, aber dann wird es eine parametrisierte generische Erweiterungsmethode, die ein Tupel nehmen würde. Ich habe Varios Syntax versucht, aber ohne Glück. Ich habe keine Information gefunden, ob dies momentan in F # unterstützt wird oder nicht. Wenn jemand weiß, lass es mich wissen.

Antwort

3

Wenn ich Ihre Frage richtig verstehe, ist die Antwort nein. Section 8.12.1 of the spec (Importierte C# Extensions Mitglieder) enthält diesen Text:

C# -defined Verlängerungselemente zur Verfügung zu F # -Code in Umgebungen gemacht werden, wo die C# -authored Montag und eine offene Deklaration von der entsprechenden Namensraum referenziert ist ist in Wirkung. Allerdings einige Einschränkungen gelten, insbesondere

  • C# Verlängerungselemente, deren „dieses“ Parameter ist eine Variable-Typ sind nicht zur Verfügung gestellt F # -Code in dieser Version von F #

  • C# Verlängerungselemente dessen „this“ Parameter ist ein Array-Typ sind nicht zur Verfügung F # -Code in dieser Version von F #

gemacht

Dies erklärt, warum einige Erweiterungsmethoden von C# funktionieren (z. die in System.Linq), während die, die Sie versuchen zu verwenden, nicht.

Darüber hinaus können native F # -Erweiterungsmethoden nur so definiert werden, als ob sie auf tatsächliche Typdefinitionen gesetzt wären. Insbesondere können Sie keine F # -Erweiterungsmethode für einen geschlossenen generischen Typ definieren (z. B. IEnumerable<string>), noch können Sie eine Erweiterungsmethode für eine generische Typvariable definieren.

+0

Danke für die Antwort! –

4

Da kvb erwähnt, ist es in F # 2.0 nicht möglich. In diesem speziellen Fall würde ich Rhino.Mocks Fluent Interface wickeln, um es in F # mehr idiomatische zu machen, zum Beispiel:

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. (sorry für den Stecker, aber ich glaube wirklich, es ist hier relevant)

+0

Marurcio, Vielen Dank für die Erklärung. Ja, ich kam auch zu der gleichen Schlussfolgerung, dass solche Erweiterungen, die in C# recht nützlich sind, F # nicht so viel Nutzen bringen würden, und es gibt andere (und bessere) Möglichkeiten, dies in F # auszudrücken. –

Verwandte Themen