Stavo guardando qualche esempio di codice C # e ho notato che un esempio racchiudeva il return in ().
Ho sempre fatto:
return myRV;
C'è una differenza facendo:
return (myRV);
Risposte:
AGGIORNAMENTO: Questa domanda è stata oggetto del mio blog il 12 aprile 2010 . Grazie per la divertente domanda!
In pratica non c'è differenza.
In teoria potrebbe esserci una differenza. Ci sono tre punti interessanti nella specifica C # in cui questo potrebbe presentare una differenza.
Innanzitutto, la conversione di funzioni anonime per delegare tipi e alberi delle espressioni. Considera quanto segue:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1è chiaramente legale. È F2? Tecnicamente no. La specifica dice nella sezione 6.5 che c'è una conversione da un'espressione lambda a un tipo di delegato compatibile. È un'espressione lambda ? No. È un'espressione tra parentesi che contiene un'espressione lambda .
Il compilatore Visual C # fa una piccola violazione delle specifiche qui e ignora le parentesi per te.
Secondo:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
F3è legale. È F4? No. La sezione 7.5.3 afferma che un'espressione tra parentesi non può contenere un gruppo di metodi. Ancora una volta, per tua comodità violiamo le specifiche e consentiamo la conversione.
Terzo:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
F5è legale. È F6? No. La specifica afferma che esiste una conversione dallo zero letterale a qualsiasi tipo enumerato. " (0)" non è lo zero letterale, è una parentesi seguita dallo zero letterale, seguito da una parentesi. Violiamo la specifica qui e in realtà consentiamo qualsiasi espressione di costante di tempo di compilazione uguale a zero , e non solo zero letterale.
Quindi, in ogni caso, ti permettiamo di farla franca, anche se tecnicamente farlo è illegale.
Ci sono casi d'angolo in cui la presenza di parentesi può avere effetto sul comportamento del programma:
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;
}
Spero che non lo vedrai mai in pratica.
Un buon modo per rispondere a domande come questa è usare Reflector e vedere cosa viene generato IL. Puoi imparare molto sulle ottimizzazioni del compilatore e simili decompilando gli assembly.