Operators as method parameters in C#
I don't think it's possible to use operators as a parameters to methods in C# 3.0 but is there a way to emulate that or some syntactic sugar that makes it seem like that's what's going on?
I ask because I recently implemented the thrush combinator in C# but while translating Raganwald's Ruby example
(1..100).select(&:odd?).inject(&:+).into { |x| x * x }
Which reads "Take the numbers from 1 to 100, keep the od开发者_开发知识库d ones, take the sum of those, and then answer the square of that number."
I fell short on the Symbol#to_proc stuff. That's the &: in the select(&:odd?)
and the inject(&:+)
above.
Well, in simple terms you can just use a lambda:
public void DoSomething(Func<int, int, int> op)
{
Console.WriteLine(op(5, 2));
}
DoSomething((x, y) => x + y);
DoSomething((x, y) => x * y);
// etc
That's not very exciting though. It would be nice to have all those delegates prebuilt for us. Of course you could do this with a static class:
public static class Operator<T>
{
public static readonly Func<T, T, T> Plus;
public static readonly Func<T, T, T> Minus;
// etc
static Operator()
{
// Build the delegates using expression trees, probably
}
}
Indeed, Marc Gravell has done something very similar in MiscUtil, if you want to look. You could then call:
DoSomething(Operator<int>.Plus);
It's not exactly pretty, but it's the closest that's supported at the moment, I believe.
I'm afraid I really don't understand the Ruby stuff, so I can't comment on that...
The following is direct, literal (as much as possible) C# translation:
(Func<int>)(x => x * x)(
Enumerable.Range(1, 100)
.Where(x => x % 2 == 1)
.Aggregate((x, y) => x + y))
Specifically:
- blocks:
{||}
- become lambdas:=>
select
becomesWhere
inject
becomesAggregate
into
becomes a direct call on a lambda instance
精彩评论