Je viens de réaliser que dans un certain endroit dans mon code, j’ai l’instruction de retour à l’intérieur de la serrure et parfois à l’extérieur. Quel est le meilleur ?
1)
2)
Lequel dois-je utiliser ?
Je viens de réaliser que dans un certain endroit dans mon code, j’ai l’instruction de retour à l’intérieur de la serrure et parfois à l’extérieur. Quel est le meilleur ?
1)
2)
Lequel dois-je utiliser ?
Essentiellement, qui jamais rend le code plus simple. Seul point de sortie est un bel idéal, mais je ne pliez pas le code de la forme, juste pour y parvenir... Et si l'alternative est de déclarer une variable locale (à l'extérieur de la serrure), l'initialisation (à l'intérieur de la serrure) et ensuite de le retourner (à l'extérieur de la serrure), alors je dirais qu'un simple "retour foo" à l'intérieur de la serrure est beaucoup plus simple.
Pour montrer la différence de l'IL, permet de code:
static class Program
{
static void Main() { }
static readonly object sync = new object();
static int GetValue() { return 5; }
static int ReturnInside()
{
lock (sync)
{
return GetValue();
}
}
static int ReturnOutside()
{
int val;
lock (sync)
{
val = GetValue();
}
return val;
}
}
(notez que je serais heureux de soutenir que ReturnInside
est plus simple/nettoyeur peu de C#)
Et regardez le IL (mode release, etc):
.method private hidebysig static int32 ReturnInside() cil managed
{
.maxstack 2
.locals init (
[0] int32 CS$1$0000,
[1] object CS$2$0001)
L_0000: ldsfld object Program::sync
L_0005: dup
L_0006: stloc.1
L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object)
L_000c: call int32 Program::GetValue()
L_0011: stloc.0
L_0012: leave.s L_001b
L_0014: ldloc.1
L_0015: call void [mscorlib]System.Threading.Monitor::Exit(object)
L_001a: endfinally
L_001b: ldloc.0
L_001c: ret
.try L_000c to L_0014 finally handler L_0014 to L_001b
}
method private hidebysig static int32 ReturnOutside() cil managed
{
.maxstack 2
.locals init (
[0] int32 val,
[1] object CS$2$0000)
L_0000: ldsfld object Program::sync
L_0005: dup
L_0006: stloc.1
L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object)
L_000c: call int32 Program::GetValue()
L_0011: stloc.0
L_0012: leave.s L_001b
L_0014: ldloc.1
L_0015: call void [mscorlib]System.Threading.Monitor::Exit(object)
L_001a: endfinally
L_001b: ldloc.0
L_001c: ret
.try L_000c to L_0014 finally handler L_0014 to L_001b
}
Donc, au niveau IL qu'ils sont [donner ou prendre quelques noms] identique (j'ai appris quelque chose ;-p).
En tant que tel, la seule raisonnable de comparaison est le (très subjective) de la loi de codage local style... je préfère ReturnInside
de la simplicité, mais je n'arrive pas à être excité à propos.
Si penser la serrure à l’extérieur est plus beau, mais soyez prudent si vous finissez par modifier le code pour :
Si f() doit être appelé avec le verrou détenu puis il doit évidemment être à l’intérieur de la serrure, gardant ainsi retourne à l’intérieur de la serrure par souci de cohérence logique.
Ça dépend,
Je vais aller à contre courant ici. En général, je serait de retour à l'intérieur de la serrure.
Habituellement, la variable mydata est une variable locale. Je suis fan de déclarer des variables locales alors que je les initialiser. J'ai rarement des données pour initialiser ma valeur de retour de l'extérieur de ma serrure.
Donc votre comparaison est en fait erronée. Alors que, idéalement, la différence entre les deux options que vous aviez écrit, qui semble donner le feu vert pour le cas 1, dans la pratique, il est un peu plus laide.
void example() {
int myData;
lock (foo) {
myData = ...;
}
return myData
}
vs
void example() {
lock (foo) {
return ...;
}
}
- Je trouver des cas 2 à être beaucoup plus facile à lire et plus difficile à vis en place, en particulier pour les courts extraits.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.