7
votes

Manière élégante d'éviter NullReferenceException dans C #

Je veux faire ce xxx

si l'une des propriétés est null, je veux que la voie soit nulle, ou "" serait mieux.

Y a-t-il un moyen élégant de le faire sans ternaires?

Idéalement, je voudrais ce comportement (sans la performance horrible et la laideur) Chemin de chaîne; xxx

merci


1 commentaires

J'ai mal lu et supprimé le commentaire


4 Réponses :


2
votes

Le chemin le plus court et le plus performant consiste à effectuer le chèque null contre tous les niveaux. Pour la réutilisation, vous pouvez envelopper ce code dans une fonction d'assistance ou peut-être une méthode d'extension. Cela vous permettra d'y accéder en toute sécurité via cette fonction, mais effectuez toujours systématiquement le chèque NULL.

Exemple: P>

public void DoSomething()
{
  // Get the path, which may be null, using the extension method
  var contextPath = HttpContext.Current.RequestPath;
}


public static class HttpContextExtensions
{
  public static string RequestPath(this HttpContext context)
  {
    if (context == null || context.Request == null)
    {
      return default(string);
    }

    return context.Request.ApplicationPath;
  }
}


1 commentaires

C'est court parce qu'il encapsule les chèques d'une méthode réutilisable; Signification que chaque fois que vous souhaitez obtenir la valeur, il n'est qu'un seul appel de méthode. C'est mieux que d'essayer de réaliser systématiquement les mêmes chèques nuls dans de nombreux endroits et aussi plus simple.



11
votes

[modifier]

c # 6 a été publié il y a quelque temps et il est expédié avec un opérateur de propagation null ?. code>, qui simplifierait votre cas à: p>

    public static class Extensions
    {
    // safe null-check.
    public static TOut IfNotNull<TIn, TOut>(this TIn v, Func<TIn, TOut> f) 
            where TIn : class  
            where TOut: class 
            { 
                    if (v == null) return null; 
                    return f(v); 
            }       
    }


5 commentaires

Toute façon raisonnable de remplacer un opérateur pour faire cela?


@Ak_ Nope, vous ne pouvez pas simplement définir votre propre opérateur de marque et remplacer ... ce serait méchant dans ce cas :) .NET Équipe est au courant des «demandes» faites pour ce type de fonctionnalité, mais afaik il a gagné 't Expédier en C # 5 -> ici et ici


(Suite, bah, timeout sur les modifications) Je ne peux pas voir un moyen de remplacer cette fonctionnalité en tant qu'opérateur, compte tenu de l'acceptation d'une expression Lambda - je ne sais pas si cela est possible, mais même si c'était laid :). En outre surcharger un opérateur existant pour un type arbitraire (s'il était même possible) révélerait un nouveau champ pour les collisions et les WTF inattendus.


Ajout de la méthode d'extension que vous avez utilisée dans votre exemple. Belle solution!


Aimer! Ajout de la méthode d'extension à notre bibliothèque-cadre également.



4
votes

mise à jour (novembre 2014)

C # 6 contient quelque chose appelé le Opérateur de propagation NULL , ce qui signifie qu'il y a un soutien linguistique à cela. Votre exemple peut être écrit comme suit en C # 6: xxx

si l'une des pièces contient NULL, l'expression complète retournera NULL.


Vous pouvez écrire quelque chose comme ceci: xxx

le moyen le plus simple d'implémenter ce nullhelpers.getvalueornull est probablement quelque chose comme ceci: < pré> xxx

mais de loin le moyen le plus cool de résoudre ce problème consiste à utiliser des arbres d'expression: xxx

C'est aussi le moyen le plus lent de faire des choses, Étant donné que chaque appel fera une ou plusieurs invocations de compilateur JIT, mais ...

Il est toujours cool; -)


2 commentaires

Je ne pense pas que le deuxième exemple fonctionne ... ne devrait-il pas commencer à partir du bas de l'expression?


@Ak_: C'est ce que membres.Reverse (); est pour :-). Testez-le vous-même.



2
votes

En mai 2012, lorsque vous avez posé la question, je n'ai pas vu une solution plus simple que l'essai ... Catch Vous avez fourni. La seule alternative - vérifier chaque partie contre NULL avec "si" ou "?" avait l'air plus laid (mais est peut-être un peu plus rapide).

Soit vous deviez écrire: xxx

ou: xxx < P> Les deux le font sans manipuler des exceptions. Notez que les deux utilisent des "raccourcis" pour avorter le chèque si une valeur nulle est trouvée.


Mise à jour (décembre 2017): Depuis c # version 6 et supérieure, Il existe une meilleure solution disponible, appelé Elvis -Opérator (également appelé opérateur null-coalescent ?. et x? [i] pour les tableaux), que vous pouvez utiliser. L'exemple ci-dessus xxx

semble beaucoup plus agréable de cette façon: xxx

qui fait exactement la Idem et est imho beaucoup plus que le sucre syntaxiste "juste". Combiné avec un ?? Valeur Vous pouvez facilement remplacer null par une autre valeur, par exemple xxx

ceci fait la trajectoire variable vide si aucune valeur non nulle ne peut être obtenue.


0 commentaires