4 ms·
I primarily use F# over C#, and I would prefer the interface version over the functions in many cases. An interface makes it a bit more explicit and self-explan
by sparkie 8y ago
I primarily use F# over C#, and I would prefer the interface version over the functions in many cases. An interface makes it a bit more explicit and self-explanatory what is expected to be passed. A Func<List<int>, List<int>> is not very meaningful and potentially ambiguous. Obviously, anywhere you expect more than one function, an interface is more desirable because it avoid the need to pass around multiple objects.
One thing that makes it a bit nicer in F# than in C# is that you can define object expressions wherever an interface is expected, so there's no need to declare a new type in the static scope somewhere (similar is possible in Java).
DoSomething { new ISortAlgorithm with
member this.Sort values = ... }
values
In terms of how they work, there's not really much difference. If something expects a function and you need to capture some local variable within that function, the framework will create a new type for that closure anyway.
- mobiliakas1 8y agoYou can use delegates in C# for that. delegate List<int> SortAlgorithm(List<int> values); List<int> QuickSort(List<int> values) => values; // Do QuickSort List<int> MergeSort(List<int> values) => values; // Do QuickSort void DoSomething(SortAlgorithm sort, List<int> values) { var sorted = sort(values); } public void Main() { var values = new List<int> { 9, 1, 5, 7 }; DoSomething(QuickSort, values); }
- sparkie 8y agoYes, my point was more that they're pretty much the same thing. A delegate and an interface with a single method are essentially isomorphic in their behaviour. The delegate obviously breaks down when you have more than one method. For that interfaces work just fine. Even in the case of using a delegate where you capture variables, the C# compiler creates a new type, instantiates it and passes the method in place of the delegate. It's hardly any different to deriving from an interface. I just tend to use interfaces more out of habit even for single methods. Creating an object expression in F# is pretty much the same outcome as creating a closure in C#. EDIT: I guess the other problem is that F# functions are not directly compatible with Func<_> and Action<_> types, so when calling a C# function expecting these, you need to wrap the call in an anonymous function. C# interfaces and F# classes are compatible though.