Операторы как параметры метода в C # - PullRequest
8 голосов
/ 07 октября 2009

Я не думаю, что можно использовать операторы в качестве параметров для методов в C # 3.0, но есть ли способ подражать этому или некоторому синтаксическому сахару, который заставляет думать, что это происходит?

Я спрашиваю, потому что недавно я реализовал комбинатор молочницы в C # , но при переводе Пример Ruby Раганвальда

(1..100).select(&:odd?).inject(&:+).into { |x| x * x }

Что гласит «Возьмите числа от 1 до 100, оставьте нечетные, возьмите их сумму, а затем ответьте на квадрат этого числа».

Я потерпел неудачу с Symbol # to_proc . Это &: в select(&:odd?) и inject(&:+) выше.

Ответы [ 2 ]

8 голосов
/ 07 октября 2009

Ну, проще говоря, вы можете просто использовать лямбду:

public void DoSomething(Func<int, int, int> op)
{
    Console.WriteLine(op(5, 2));
}

DoSomething((x, y) => x + y);
DoSomething((x, y) => x * y);
// etc

Это не очень интересно, хотя. Было бы неплохо, чтобы все эти делегаты были подготовлены для нас. Конечно, вы можете сделать это с помощью статического класса:

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
     }
}

Действительно, Марк Гравелл сделал нечто очень похожее в MiscUtil , если хотите посмотреть. Вы можете позвонить:

DoSomething(Operator<int>.Plus);

Это не совсем красиво, но, я полагаю, это самое близкое, что поддерживается на данный момент.

Боюсь, я действительно не понимаю, что такое Ruby, поэтому я не могу это комментировать ...

2 голосов
/ 07 октября 2009

Ниже приведен прямой, буквальный (насколько это возможно) перевод на C #:

(Func<int>)(x => x * x)(
    Enumerable.Range(1, 100)
        .Where(x => x % 2 == 1)
        .Aggregate((x, y) => x + y))

В частности:

  • блоков: {||} - стать лямбдами: =>
  • select становится Where
  • inject становится Aggregate
  • into становится прямым вызовом для лямбда-экземпляра
...