Depuis que jeQuoi de mieux: id ?? 0 == 0 ou id == null || id == 0?
public class Foo
{
public int? Id { get; set; }
}
Quoi de mieux
if ((Id ?? 0) == 0) {}
ou
if (Id == null || Id == 0)
?
Depuis que jeQuoi de mieux: id ?? 0 == 0 ou id == null || id == 0?
public class Foo
{
public int? Id { get; set; }
}
Quoi de mieux
if ((Id ?? 0) == 0) {}
ou
if (Id == null || Id == 0)
?
Je recommande le deuxième. C'est plus lisible.
Et comme je l'ai remarqué, moins de personnes connaissent l'opérateur ??
.
+1: D'accord. Du point de vue de la lisibilité, le second est supérieur, et je ne pense pas que la performance soit un problème ici. Les deux seront assez rapides. –
Je suis toujours d'accord que le second est plus lisible. Mais je n'achète pas (manque de) familiarité avec '??' comme argument. Si vous ne connaissez pas la langue, allez l'apprendre. L'ignorance de la syntaxe du langage n'est pas une excuse. –
Je préfère la lisibilité sur l'intelligence (presque) à chaque fois, alors je vais certainement avec: if (Id == null || Id == 0)
serait encore mieux:
if(!Id.HasValue || Id == 0)
{
}
Non car 'Id.Value = 0', c'est-à-dire qu'il a une valeur et 0 – abatishchev
Cela fonctionnerait si c'était: if (! Id.HasValue || Id == 0) {} – TurBas
Je viens de réaliser le léger défaut - mis à jour –
if(Id.GetValueOrDefault() == 0)
est également une option. En termes de performance, je doute qu'il y ait une réelle différence, et en tout cas vous feriez de la micro-optimisation, ce qui est rarement bénéfique.
Depuis c'est étiqueté « performance », voici mon conseil général sur des sujets tels que je pense toujours est valable ici:
pour développer:
Il pourrait très bien être des choses présentes dans votre code cela rend ces conseils de micro-optimisation invalides ou non-optimaux, donc votre meilleure option concernant la performance est juste de la mesurer. Assurez-vous de mesurer suffisamment d'itérations d'une boucle en mesurant que le temps du petit code 1 va être perturbé par toutes les autres choses que votre machine invalide tout l'exercice.
En ce qui concerne les micro-optimisations, ne vous inquiétez pas. Choisissez celui que vous (et quiconque d'autre va maintenir le code) est le plus à l'aise avec, et se soucier des micro-optimisations si, et quand, vous avez réellement besoin de.
Personnellement, j'écris souvent le premier, c'est à dire.
if (o ?? 0 == 0)
ou, dans le cas des cordes:
if ((s ?? string.Empty).Length == 0)
Cependant, en termes de lisibilité et « ce qui semble le mieux », c'est un problème abri à vélo. Aller avec ce que vous voulez vous-même et se sentir à l'aise avec, et passer à de plus gros problèmes.
Modifier, Ok, j'ai arrêté de penser quelque part avant le dernier exemple de code.Je combiné deux choses différentes que je fais:
null
sauf si cela est utileif (PropertyName.Length == 0)
Bien sûr, dans cet exemple particulier Je voudrais utiliser l'une des deux suivantes:
if (string.IsNullOrEmpty(s))
if (string.IsNullOrWhiteSpace(s))
(uniquement dans la version 4.0, et seulement si vous avez besoin)Je trouve '(s ?? string.Empty) .Length == 0' horrible quand vous avez' string.IsNullOrEmpty (s) '. –
Ouais, je micro-optimisé: P –
Cependant, considérons le cas général: '(s ??" ") .Length == x' .. Je trouve ça parfaitement bien - sauf pour avoir un null du tout, c'est ... –
Si vous utilisez ce code une seule fois, ce n'est pas tout à fait grande différence ce qu'il faut utiliser (mais, je préfère deuxième - il est plus facile à lire). Sinon, j'aimerais donner un nom de condition que je vérifie ici. Par exemple.
public class Foo
{
public int? Id { get; set; }
public bool IsNew
{
get
{
return (Id == null) || (Id == 0);
}
}
}
Maintenant, le code indique ce que vous vérifiez. Et il est lisible comme un livre
if (IsNew) {}
J'aime mieux mes livres quand ils ont des sujets dans leurs phrases. Lisible comme un livre serait: 'if (this.IsNew)'. (Juste en plaisantant, je ne vois rien de mal à omettre 'this' ici) –
Eh bien, peut-être que c'est un Haiku :) –
je vous recommande le second aussi le code doit de préférence comme suit
if (null == Id || 0 == Id)
Pouvez-vous expliquer pourquoi? Même si c'est pour des gains de performance, le gain serait sûrement minime et/ou équivalent à la ligne d'origine au moment où il serait optimisé. De plus, il se sent juste en arrière et IMO moins lisible. –
elkdanger, c'est la pratique normale depuis les jours de VB. Pour le contrôle égal, nous spécifierons single = not two ==. Il y a donc plusieurs chances que la valeur du côté droit soit affectée à la valeur de gauche. Garder cette pratique dans mon esprit, je l'ai juste suggéré. Ce n'est pas un must. – Elangesh
Egalement pratique courante en C/C++ où la condition d'une instruction if sera un entier et si mal typer '=' au lieu de '==' n'entraînera pas d'erreur de compilation. En plaçant la valeur constante sur la gauche, il y aura une erreur de compilation lors d'une erreur de frappe car le compilateur ne vous laissera pas affecter une variable à une constante (mais l'inverse est correct, d'où le problème.) ( –
Je pense que dans votre cas, le premier exemple pourrait être très légèrement plus rapide.
Je l'ai fait les deux façons LINQPad
void Main()
{
Foo f = new Foo();
if ((Id ?? 0) == 0) {} // if (f.Id == null || f.Id == 0) {}
}
// Define other methods and classes here
public class Foo
{
public int? Id { get; set; }
}
L'IL pour if ((Id ?? 0) == 0) {}
est la suivante:
IL_0000: newobj UserQuery+Foo..ctor
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt UserQuery+Foo.get_Id
IL_000C: stloc.1
IL_000D: ldloca.s 01
IL_000F: call System.Nullable<System.Int32>.get_HasValue
IL_0014: brtrue.s IL_0019
IL_0016: ldc.i4.0
IL_0017: br.s IL_0020
IL_0019: ldloca.s 01
IL_001B: call System.Nullable<System.Int32>.GetValueOrDefault
Foo.get_Id:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+Foo.<Id>k__BackingField
IL_0006: ret
Foo.set_Id:
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld UserQuery+Foo.<Id>k__BackingField
IL_0007: ret
Foo..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret
IL pour if (f.Id == null || f.Id == 0)
est inférieure à - note deux appels à get_HasValue
IL_0000: newobj UserQuery+Foo..ctor
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt UserQuery+Foo.get_Id
IL_000C: stloc.1
IL_000D: ldloca.s 01
IL_000F: call System.Nullable<System.Int32>.get_HasValue
IL_0014: brfalse.s IL_0031
IL_0016: ldloc.0
IL_0017: callvirt UserQuery+Foo.get_Id
IL_001C: stloc.2
IL_001D: ldloca.s 02
IL_001F: call System.Nullable<System.Int32>.GetValueOrDefault
IL_0024: brtrue.s IL_002F
IL_0026: ldloca.s 02
IL_0028: call System.Nullable<System.Int32>.get_HasValue
IL_002D: br.s IL_0030
IL_002F: ldc.i4.0
Foo.get_Id:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+Foo.<Id>k__BackingField
IL_0006: ret
Foo.set_Id:
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld UserQuery+Foo.<Id>k__BackingField
IL_0007: ret
Foo..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret
Peut-être que je devrais en sortir plus!
Pourquoi L'IL génère tout ce qui est pertinent à la question de la performance? ** L'IL ne fonctionne jamais. ** Ce qui est pertinent à la question de la performance est quel code génère la * gigue d'optimisation *, et la gigue va probablement inline l'appel à HasValue, puisqu'il ne s'agit que d'une seule lecture d'un champ booléen sur une structure –
Merci pour l'info Eric Je suppose que je n'avais pas réalisé que l'optimisation réelle se produisait entre IL et le code machine plutôt qu'entre C# et IL, Je viens juste de voir ta réponse ici: http://stackoverflow.com/questions/2162541/is-the-c-compiler-smart-enough-to-optimize-this-code qui l'explique plus en détail. –
qui est plus lisible?> –
depuis que vous avez tagué votre question avec "performance" - voulez-vous dire "meilleur" en termes de performance ou en termes de lisibilité? –
Vous devriez toujours essayer de tracer votre question autant que possible. Lorsque vous demandez «quoi de mieux», il est utile de décrire le type d'échelle que vous comparez. c'est à dire. "X semble-t-il mieux que Y" ou "X tourne-t-il plus vite que Y" ou "X utilisera-t-il plus de mémoire que Y", etc. Personnellement j'aime les bananes, c'est beaucoup mieux que n'importe lequel de vos exemples. –