Оператор определения C # - PullRequest
       47

Оператор определения C #

6 голосов
/ 26 февраля 2010

еще в школе мы написали компилятор, в котором фигурные скобки по умолчанию выполняли все выражения и возвращали последнее значение ... чтобы вы могли написать что-то вроде:

int foo = { printf("bar"); 1 };

Есть ли что-то эквивалентное в C #? Например, если я хочу написать лямбда-функцию, которая имеет побочный эффект.

Дело не в лямбда-побочном эффекте (просто пример), а в том, что если есть эта функциональность ... например, в lisp, у вас есть progn

Ответы [ 5 ]

7 голосов
/ 26 февраля 2010

В принципе ответ Влада правильный, и вам не нужно заранее объявлять лямбда-функцию в качестве делегата.

За исключением того, что ситуация не так проста в C #, потому что компилятор не может решить, должно ли синтаксическое лямбда-выражение быть скомпилировано как делегат (например, Func<int>) или дерево выражений (например, Expression<Func<int>>), а также может быть любым другим совместимым типом делегата. Итак, вам нужно создать делегата:

int foo = new Func<int>(() => { 
  Console.WriteLine("bar"); return 1; })(); 

Вы можете немного упростить код, определив метод, который просто возвращает делегат, а затем вызвав метод - компилятор C # автоматически определит тип делегата:

static Func<R> Scope<R>(Func<R> f) { return f; }

// Compiler automatically compiles lambda function
// as delegate and infers the type arguments of 'Scope'
int foo = Scope(() => { Console.WriteLine("bar"); return 1; })(); 

Я согласен, что это уродливый трюк, который не должен использоваться :-), но это интересный факт, что это можно сделать!

7 голосов
/ 26 февраля 2010

Ничто не мешает вам иметь побочные эффекты в лямбда-выражении.

Func<int> expr = () =>
{
    Console.WriteLine("bar");
    return 1;
};
int foo = expr();
5 голосов
/ 26 февраля 2010
int foo = (() => { printf("bar"); return 1; })();

Редактировать: спасибо за конструктивную критику, должно быть

int i = ((Func<int>)(() => { printf("bar"); return 1; }))();
3 голосов
/ 26 февраля 2010

Мы рассмотрели возможность создания даже более кратких синтаксисов, чем ()=>{M();}, для определения лямбды, но нам не удалось найти синтаксис, который хорошо читается и его нелегко спутать с блоками, инициализаторами коллекции / объекта или инициализаторы массива. Вы застряли с лямбда-синтаксисом сейчас.

2 голосов
/ 26 февраля 2010

Вы говорите об анонимной функции: http://msdn.microsoft.com/en-us/library/bb882516.aspx, Я думаю.

...