Ответ 1
UPDATE: этот вопрос был тема моего блога 12 апреля 2010 года. Спасибо за забавный вопрос!
На практике нет разницы.
В теории может быть разница. В спецификации С# есть три интересных момента, где это может привести к различию.
Во-первых, преобразование анонимных функций для делегирования типов и деревьев выражений. Рассмотрим следующее:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1
является явно законным. Является F2
? Технически, нет. Спецификация говорит в разделе 6.5, что есть преобразование из лямбда-выражения в совместимый тип делегата. Это лямбда-выражение? Нет. Это выражение в скобках, содержащее лямбда-выражение.
Компилятор Visual С# делает здесь небольшое нарушение спецификации и отбрасывает скобки для вас.
Во-вторых:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
F3
является законным. Является F4
? Нет. В разделе 7.5.3 указано, что выражение в скобках не может содержать группу методов. Опять же, для вашего удобства мы нарушаем спецификацию и разрешаем преобразование.
Третье:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
F5
является законным. Является F6
? Нет. Спецификация заявляет, что есть преобразование из буквального нуля в любой перечислимый тип. "(0)
" не является буквальным нулем, это скобка, за которой следует буквальный нуль, за которым следует скобка. Мы нарушаем спецификацию здесь и фактически разрешаем любое выражение постоянной времени компиляции равным нулю, а не только буквальное значение.
Таким образом, в каждом случае мы позволяем вам уйти от него, хотя технически это незаконно.