C# 6 Mise à jourpièges possibles d'utilisation de cette (méthode d'extension en fonction) sténographie
En C#6 ?.
is now a language feature:
// C#1-5
propertyValue1 = myObject != null ? myObject.StringProperty : null;
// C#6
propertyValue1 = myObject?.StringProperty;
La question ci-dessous applique toujours aux anciennes versions, mais si le développement d'une nouvelle application à l'aide le nouvel opérateur ?.
est une bien meilleure pratique.
Original Question:
Je veux régulièrement accéder à des propriétés des objets éventuellement nuls:
string propertyValue1 = null;
if(myObject1 != null)
propertyValue1 = myObject1.StringProperty;
int propertyValue2 = 0;
if(myObject2 != null)
propertyValue2 = myObject2.IntProperty;
Et ainsi de suite ...
J'utilise si souvent que j'ai extrait pour cela.
Vous pouvez raccourcir cela dans une certaine mesure avec une ligne si:
propertyValue1 = myObject != null ? myObject.StringProperty : null;
Cependant c'est un peu maladroit, surtout si la mise en beaucoup de propriétés ou si plus d'un niveau peut être nul, par exemple:
propertyValue1 = myObject != null ?
(myObject.ObjectProp != null ? myObject.ObjectProp.StringProperty) : null : null;
Ce que je veux vraiment est la syntaxe ??
de style, qui fonctionne très bien pour les types null directement:
int? i = SomeFunctionWhichMightReturnNull();
propertyValue2 = i ?? 0;
Alors je suis venu avec ce qui suit:
public static TResult IfNotNull<T, TResult>(this T input, Func<T, TResult> action, TResult valueIfNull)
where T : class
{
if (input != null) return action(input);
else return valueIfNull;
}
//lets us have a null default if the type is nullable
public static TResult IfNotNull<T, TResult>(this T input, Func<T, TResult> action)
where T : class
where TResult : class
{ return input.IfNotNull(action, null); }
Cela nous me permet cette syntaxe:
propertyValue1 = myObject1.IfNotNull(x => x.StringProperty);
propertyValue2 = myObject2.IfNotNull(x => x.IntProperty, 0);
//or one with multiple levels
propertyValue1 = myObject.IfNotNull(
o => o.ObjectProp.IfNotNull(p => p.StringProperty));
Cela simplifie ces appels, mais je ne suis pas sûr de vérifier ce type de méthode d'extension - Cela rend le code un peu plus facile à lire, mais au prix de l'extension de l'objet. Cela apparaîtrait sur tout, bien que je puisse le mettre dans un espace de noms spécifiquement référencé.
Cet exemple est plutôt simple, un peu plus complexe comparerions deux propriétés de l'objet nullables:
if((obj1 == null && obj2 == null) ||
(obj1 != null && obj2 != null && obj1.Property == obj2.Property))
...
//becomes
if(obj1.NullCompare(obj2, (x,y) => x.Property == y.Property)
...
Quels sont les pièges de l'utilisation des extensions de cette façon? Les autres codeurs sont-ils susceptibles d'être confus? Est-ce juste un abus d'extensions?
Je suppose que ce que je veux vraiment ici est un compilateur/extension linguistique:
propertyValue1 = myObject != null ? myObject.StringProperty : null;
//becomes
propertyValue1 = myObject?StringProperty;
Cela rendrait le cas complexe beaucoup plus facile:
propertyValue1 = myObject != null ?
(myObject.ObjectProp != null ? myObject.ObjectProp.StringProperty) : null
//becomes
propertyValue1 = myObject?ObjectProp?StringProperty;
Cela ne fonctionne que pour la valeur types, mais vous pouvez renvoyer des équivalents NULL:
int? propertyValue2 = myObject?ObjectProp?IntProperty;
//or
int propertyValue3 = myObject?ObjectProp?IntProperty ?? 0;
Oui, j'ai demandé Mads directement à TechEd - fondamentalement cette fonctionnalité manque toujours la coupe, ils pourraient encore l'ajouter une future version C# – Keith
@Keith Merci pour la mise à jour! (Il ne peut pas faire de mal de rappeler à l'équipe C# que les clients trouveraient cela utile.) –
Ils sont maintenant sérieusement le considérer: http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/ at-last-c-is-getting-parfois-appelé-the-safe-navigation-operator.aspx –