Я смотрел пример кода C # и заметил, что один пример заключил return в ().
Я всегда только что делал:
return myRV;
Есть ли разница в выполнении:
return (myRV);
ОБНОВЛЕНИЕ: этот вопрос был темой моего блога 12 апреля 2010 года . Спасибо за забавный вопрос!
На практике разницы нет.
В теории не может быть разница. В спецификации C # есть три интересных момента, в которых это может иметь значение.
Во-первых, преобразование анонимных функций в типы делегатов и деревья выражений. Обратите внимание на следующее:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1
явно законно. Есть F2
? Технически нет. В спецификации говорится в разделе 6.5, что существует преобразование лямбда-выражения в совместимый тип делегата. Это лямбда-выражение ? Нет. Это выражение в скобках , содержащее лямбда-выражение .
Компилятор Visual C # делает здесь небольшое нарушение спецификации и отбрасывает скобки за вас.
Второй:
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)
" не является буквальным нулем, это скобка, за которой следует буквальный ноль, за которой следует скобка. Мы нарушаем здесь спецификацию и фактически позволяем любому выражению константы времени компиляции равняться нулю , а не только буквальному нулю.
Поэтому в каждом случае мы позволяем вам избежать наказания за это, даже если технически это незаконно.
Есть угловые случаи, когда наличие круглых скобок может повлиять на поведение программы:
1.
using System; class A { static void Foo(string x, Action<Action> y) { Console.WriteLine(1); } static void Foo(object x, Func<Func<int>, int> y) { Console.WriteLine(2); } static void Main() { Foo(null, x => x()); // Prints 1 Foo(null, x => (x())); // Prints 2 } }
2.
using System; class A { public A Select(Func<A, A> f) { Console.WriteLine(1); return new A(); } public A Where(Func<A, bool> f) { return new A(); } static void Main() { object x; x = from y in new A() where true select (y); // Prints 1 x = from y in new A() where true select y; // Prints nothing } }
3.
using System; class Program { static void Main() { Bar(x => (x).Foo(), ""); // Prints 1 Bar(x => ((x).Foo)(), ""); // Prints 2 } static void Bar(Action<C<int>> x, string y) { Console.WriteLine(1); } static void Bar(Action<C<Action>> x, object y) { Console.WriteLine(2); } } static class B { public static void Foo(this object x) { } } class C<T> { public T Foo; }
Надеюсь, вы никогда не увидите этого на практике.
источник
Нет, кроме синтаксической разницы нет.
источник
Хороший способ ответить на подобные вопросы - использовать Reflector и посмотреть, что генерируется IL. Вы можете многое узнать об оптимизации компилятора и тому подобном, декомпилировав сборки.
источник