Игнорирование скобок
Еще один забавный вопрос на StackOverflow: существует ли в C# разница между “return something;” и “return (something);”?
Практически разницы нет.
Теоретически разница может быть. Существует три интересных замечания в спецификации языка C#, из-за которых могут возникнуть проблемы.
Первый пример: преобразование анонимных функций к делегатам или деревьям выражений (expression tree). Рассмотрим следующий код:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
Выражение F1 совершенно корректное. А как насчет F2? Технически – нет. В разделе 6.5 спецификации сказано, что существует преобразование лямбда-выражения к делегату совместимого типа. А является ли это лямбда-выражением? Нет, это выражение в скобках, которое содержит лямбда-выражение.
В этом случае компилятор немного нарушает спецификацию и отбрасывает скобки за вас.
Второй пример:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
Выражение F3 – корректное. А F4? Нет. В разделе 7.5.3 сказано, что выражение в скобках не должно содержать группу методов (method group). В этом случае ради вашего удобства мы (нечаянно!) нарушаем спецификацию и позволяем это преобразование.
Третий пример:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
Выражение F5 – корректное. А F6? Нет. В спецификации сказано о том, что существует преобразования из литерала 0 к любому перечислимому типу. "(0)" – это не литерал 0, это открывающая круглая скобка, за которой следует литерал 0, за которой следует закрывающая скобка. В этом случае мы нарушаем спецификацию; на самом деле в этом случае мы позволяем преобразование не только из литерала 0, а из любого константного выражения, равного нулю.
Так что, мы всегда позволяем использовать круглые скобки, хотя технически это и не корректно.