126 votes

C# élégante façon de vérifier si une propriété est propriété est null

En C#, de dire que vous voulez tirer une valeur hors de PropertyC dans cet exemple et ObjectA, PropertyA et PropertyB peuvent tous être null.

ObjectA.PropertyA.PropertyB.PropertyC

Comment puis-je obtenir PropertyC en toute sécurité et avec le moins de code?

Maintenant, je voudrais vérifier:

if(ObjectA != null && ObjectA.PropertyA !=null && ObjectA.PropertyA.PropertyB != null)
{
// safely pull off the value
int value = objectA.PropertyA.PropertyB.PropertyC;
}

Il serait bien de faire quelque chose de plus comme cette (pseudo-code).

int value = ObjectA.PropertyA.PropertyB ? ObjectA.PropertyA.PropertyB : defaultVal;

Peut-être encore plus effondré avec un null-coalescence de l'opérateur.

MODIFIER à l'Origine, je l'ai dit, mon second exemple est comme js, mais j'ai changé de pseudo-code, car il a été souligné à juste titre que cela ne fonctionnerait pas en js.

Merci beaucoup, Jon

28voto

Courte Extension De La Méthode:

public static TResult IfNotNull<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
  where TResult : class where TInput : class
{
  if (o == null) return null;
  return evaluator(o);
}

À l'aide de

PropertyC value = ObjectA.IfNotNull(x => x.PropertyA).IfNotNull(x => x.PropertyB).IfNotNull(x => x.PropertyC);

Cette simple méthode d'extension et beaucoup plus que vous pouvez trouver sur http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/

EDIT:

Après l'avoir utilisé pour le moment je pense que le vrai nom de cette méthode doit être IfNotNull() au lieu de l'original Avec().

16voto

Sam Points 3231

Pouvez-vous ajouter une méthode à votre classe? Si non, avez-vous pensé à utiliser des méthodes d'extension? Vous pouvez créer une méthode d'extension pour votre type d'objet appelé GetPropC().

Exemple:

public static class MyExtensions
{
    public static int GetPropC(this MyObjectType obj, int defaltValue)
    {
        if (obj != null && obj.PropertyA != null & obj.PropertyA.PropertyB != null)
            return obj.PropertyA.PropertyB.PropertyC;
        return defaltValue;
    }
}

Utilisation:

int val = ObjectA.GetPropC(0); // will return PropC value, or 0 (defaltValue)

Par ailleurs, cela suppose que vous utilisez .NET de 3 ou plus.

12voto

Thomas Levesque Points 141081

La façon dont vous le faites est correct.

Vous pourriez utiliser un truc comme celui décrit ici, à l'aide des expressions Linq :

int value = ObjectA.NullSafeEval(x => x.PropertyA.PropertyB.PropertyC, 0);

Mais c'est beaucoup plus lent qu'à vérifier manuellement chaque propriété...

11voto

rtalbot Points 1248

Refactoriser d'observer la Loi de Déméter

8voto

dtb Points 104373

Vous êtes évidemment à la recherche pour le Nullable Monade:

string result = new A().PropertyB.PropertyC.Value;

devient

string result = from a in new A()
                from b in a.PropertyB
                from c in b.PropertyC
                select c.Value;

Cela renvoie null, si l'un des nullable propriétés sont null; sinon, la valeur de Value.

class A { public B PropertyB { get; set; } }
class B { public C PropertyC { get; set; } }
class C { public string Value { get; set; } }

Extension LINQ méthodes:

public static class NullableExtensions
{
    public static TResult SelectMany<TOuter, TInner, TResult>(
        this TOuter source,
        Func<TOuter, TInner> innerSelector,
        Func<TOuter, TInner, TResult> resultSelector)
        where TOuter : class
        where TInner : class
        where TResult : class
    {
        if (source == null) return null;
        TInner inner = innerSelector(source);
        if (inner == null) return null;
        return resultSelector(source, inner);
    }
}

Prograide.com

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.

Powered by:

X