Mise à jour: à partir de Visual Studio 2015, le compilateur C # (version 6 du langage) reconnaît désormais l' ?.
opérateur, ce qui simplifie la «vérification approfondie des null». Voir cette réponse pour plus de détails.
En plus de reconcevoir votre code, comme le
suggère cette réponse supprimée , une autre option (bien que terrible) serait d'utiliser un try…catch
bloc pour voir si une NullReferenceException
erreur se produit à un moment donné pendant cette recherche approfondie de propriété.
try
{
var x = cake.frosting.berries.loader;
...
}
catch (NullReferenceException ex)
{
// either one of cake, frosting, or berries was null
...
}
Personnellement, je ne ferais pas cela pour les raisons suivantes:
- Ça n'a pas l'air sympa.
- Il utilise la gestion des exceptions, qui doit cibler des situations exceptionnelles et non quelque chose dont vous vous attendez à ce qu'il se produise souvent au cours du fonctionnement normal.
NullReferenceException
s ne devrait probablement jamais être pris explicitement. (Voir cette question .)
Est-il donc possible d'utiliser une méthode d'extension ou serait-ce une fonctionnalité de langage, [...]
Cela devrait presque certainement être une fonctionnalité de langage (qui est disponible en C # 6 sous la forme des opérateurs .?
et ?[]
), à moins que C # n'ait déjà une évaluation paresseuse plus sophistiquée, ou à moins que vous ne souhaitiez utiliser la réflexion (qui n'est probablement pas non plus une bonne idée pour des raisons de performances et de sécurité de type).
Puisqu'il n'y a aucun moyen de passer simplement cake.frosting.berries.loader
à une fonction (elle serait évaluée et lèverait une exception de référence nulle), vous devriez implémenter une méthode de recherche générale de la manière suivante: Il prend un objets et les noms de propriétés à Chercher:
static object LookupProperty( object startingPoint, params string[] lookupChain )
{
// 1. if 'startingPoint' is null, return null, or throw an exception.
// 2. recursively look up one property/field after the other from 'lookupChain',
// using reflection.
// 3. if one lookup is not possible, return null, or throw an exception.
// 3. return the last property/field's value.
}
...
var x = LookupProperty( cake, "frosting", "berries", "loader" );
(Remarque: code modifié.)
Vous voyez rapidement plusieurs problèmes avec une telle approche. Premièrement, vous n'obtenez aucune sécurité de type et possibilité d'encadrer les valeurs de propriété d'un type simple. Deuxièmement, vous pouvez soit revenir null
si quelque chose ne va pas, et vous devrez vérifier cela dans votre fonction d'appel, ou vous lever une exception, et vous êtes de retour à votre point de départ. Troisièmement, cela pourrait être lent. Quatrièmement, cela a l'air plus laid que ce avec quoi vous avez commencé.
[...], ou est-ce juste une mauvaise idée?
Je resterais soit avec:
if (cake != null && cake.frosting != null && ...) ...
ou allez avec la réponse ci-dessus par Mehrdad Afshari.
PS: Quand j'ai écrit cette réponse, je n'ai évidemment pas considéré les arbres d'expression pour les fonctions lambda; voir par exemple la réponse de @driis pour une solution dans ce sens. Il est également basé sur une sorte de réflexion et peut donc ne pas fonctionner aussi bien qu'une solution plus simple ( if (… != null & … != null) …
), mais il peut être jugé plus agréable d'un point de vue syntaxique.