Reputation: 1482
I'm learning F# and I got to thinking. You can chain operations from normal operators, such as
let aChainedFunc = List.map func >> List.reduce func
then later you can go let result = aChainedFunc aList
to get the results of those same operations, allowing some nice reuse in a short amount of code.
But, what if you have a C# object where you want to invoke methods from that object, but pre-build the chain similarly to the F# example above?
Obviously this requires an object that can do normal a.Method1().Method2().Method3()
to make it work, but is there a way to sanely set this up to allow this to work without building a method where you pass it in instead?
Upvotes: 0
Views: 368
Reputation: 2382
in f#, you can redefine a .net function like
let foo x = a.Foo x
and
let boo y = b.Boo y
then, in your chain you just use your redefined functions like
let moo =
foo >> boo
or
let moo z =
z
|> foo
|> boo
Upvotes: 0
Reputation: 243106
If you wanted to create sequence of static method calls (or extension method calls), say SomeType.Method1
, SomeType.Method2
and OtherType.Method3
, then you can write a C# method Compose
that behaves similarly to the >>
operator in C#:
Func<T, R> Compose<T, U, R>(Func<T, U> f1, Func<U, R> f2) {
return v => f2(f2(v));
}
Then you should be able to write something like:
Compose(SomeType.Method1, SomeType.Method2).Compose(OtherType.Method3); // ...
Note that this will work only for methods taking single argument (but you could define overloaded versions that take multiple arguments and the compiler should be able to infer them).
If you're calling instance methods then there is no syntax for referring just to the method - you need some expression to invoke the method on. A little lighter way than writing a method would be to write a lambda expression:
// Chain multiple operations
Func<SomeType, SomeType> composed = v => v.Method1().Method2().Method3();
// Use chained operation two times
var v1 = composed(foo1);
var v2 = composed(foo2);
Upvotes: 2