Je regardais un exemple de code C # et j'ai remarqué qu'un exemple enveloppait le retour entre ().
J'ai toujours juste fait:
return myRV;
Y a-t-il une différence à faire:
return (myRV);
Réponses:
MISE À JOUR: Cette question a fait l'objet de mon blog le 12 avril 2010 . Merci pour la question amusante!
En pratique, il n'y a pas de différence.
En théorie, il pourrait y avoir une différence. Il y a trois points intéressants dans la spécification C # où cela pourrait présenter une différence.
Tout d'abord, la conversion de fonctions anonymes pour déléguer des types et des arborescences d'expressions. Considérer ce qui suit:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1
est clairement légal. Est-ce F2
? Techniquement, non. La spécification indique dans la section 6.5 qu'il existe une conversion d'une expression lambda en un type délégué compatible. Est-ce une expression lambda ? Non. C'est une expression entre parenthèses qui contient une expression lambda .
Le compilateur Visual C # effectue une petite violation de spécification ici et supprime la parenthèse pour vous.
Seconde:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
F3
est légal. Est-ce F4
? Non. La section 7.5.3 indique qu'une expression entre parenthèses ne peut pas contenir de groupe de méthodes. Encore une fois, pour votre commodité, nous violons les spécifications et autorisons la conversion.
Troisième:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
F5
est légal. Est-ce F6
? Non. La spécification indique qu'il y a une conversion du zéro littéral en n'importe quel type énuméré. " (0)
" n'est pas le zéro littéral, c'est une parenthèse suivie du zéro littéral, suivi d'une parenthèse. Nous violons la spécification ici et autorisons en fait toute expression de constante de temps de compilation égale à zéro , et pas seulement zéro littéral.
Donc, dans tous les cas, nous vous permettons de vous en sortir, même si cela est techniquement illégal.
Il existe des cas d'angle où la présence de parenthèses peut avoir un effet sur le comportement du programme:
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;
}
J'espère que vous ne verrez jamais cela en pratique.
Un bon moyen de répondre à des questions comme celle-ci est d'utiliser Reflector et de voir ce que IL est généré. Vous pouvez en apprendre beaucoup sur les optimisations du compilateur et autres en décompilant les assemblys.