Eu estava olhando um exemplo de código C # e percebi que um exemplo envolveu o retorno em ().
Eu sempre acabei de fazer:
return myRV;
Existe alguma diferença fazendo:
return (myRV);
Respostas:
ATUALIZAÇÃO: Esta questão foi o assunto do meu blog em 12 de abril de 2010 . Obrigado pela pergunta divertida!
Na prática, não há diferença.
Em teoria , pode haver uma diferença. Existem três pontos interessantes na especificação C # onde isso pode apresentar uma diferença.
Primeiro, a conversão de funções anônimas para delegar tipos e árvores de expressão. Considere o seguinte:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1
é claramente legal. É F2
? Tecnicamente, não. A especificação diz na seção 6.5 que há uma conversão de uma expressão lambda em um tipo de delegado compatível. Isso é uma expressão lambda ? Não. É uma expressão entre parênteses que contém uma expressão lambda .
O compilador Visual C # faz uma pequena violação de especificação aqui e descarta o parêntese para você.
Segundo:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
F3
é legal. É F4
? Não. A seção 7.5.3 afirma que uma expressão entre parênteses não pode conter um grupo de métodos. Novamente, para sua conveniência, violamos a especificação e permitimos a conversão.
Terceiro:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
F5
é legal. É F6
? Não. A especificação afirma que há uma conversão do zero literal para qualquer tipo enumerado. " (0)
" não é o zero literal, é um parêntese seguido pelo zero literal, seguido por um parêntese. Violamos a especificação aqui e permitimos qualquer expressão de constante de tempo de compilação igual a zero , e não apenas zero literal.
Portanto, em todos os casos, permitimos que você escape impune, mesmo que isso seja tecnicamente ilegal.
Existem casos extremos em que a presença de parênteses pode afetar o comportamento do programa:
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;
}
Espero que você nunca veja isso na prática.
Uma boa maneira de responder a perguntas como essa é usar o Reflector e ver o que IL é gerado. Você pode aprender muito sobre otimizações de compilador e descompilando assemblies.