45 votes

ArgumentNullException ou NullReferenceException de la méthode d'extension ?

Quel serait, selon vous, le meilleur type d'exception à lever lorsqu'une méthode d'extension est appelée sur une instance nulle (lorsque la méthode d'extension ne le permet pas) ? Étant donné que les méthodes d'extension ne sont rien d'autre que des méthodes statiques, on pourrait dire que ce devrait être ArgumentNullException, mais d'un autre côté, elles sont utilisées comme des méthodes d'instance et il serait donc plus naturel d'utiliser NullReferenceException. Prenons l'exemple suivant :

public static string ToInvariantString(this IFormattable value, string format)
{
    return value.ToString(format, CultureInfo.InvariantCulture);
}

De cette façon, une NullReferenceException sera levée si le paramètre de valeur est nul.

L'autre exemple serait :

public static string ToInvariantString(this IFormattable value, string format)
{
    if (value == null) throw new ArgumentNullException("value");
    return value.ToString(format, CultureInfo.InvariantCulture);
}

EDIT : Dans certaines réponses, vous avez souligné qu'une méthode d'extension peut être appelée comme une méthode statique et que, dans ce cas, une exception de référence nulle serait erronée, ce qui est un excellent point, et en fait l'une de mes préoccupations, je ne sais pas pourquoi j'ai oublié de le mentionner dans la question en premier lieu.

Quelqu'un a également fait remarquer que c'était une erreur de lancer une NullReferenceException, et c'est vrai. C'est pourquoi je ne la lève pas, je la laisse simplement se produire (laisser le CLR la lever) en ne gardant pas la méthode.

Je pense que je préfère l'exception ArgumentNullException (c'est ce que j'ai utilisé jusqu'à présent) mais je pense toujours qu'il y a au moins une place pour argumenter pour ou contre l'exception NullReferenceException puisqu'elle semble plus naturelle dans la plupart des endroits où la méthode va être utilisée.

43voto

JaredPar Points 333733

En général, exceptions comprises, vous devez traiter une méthode d'extension comme s'il s'agissait d'une méthode statique normale. Dans ce cas, vous devez lever une ArgumentNullException.

Lancer une NullReferenceException ici est une mauvaise idée pour quelques raisons

  • Une référence nulle ne s'est pas produite en réalité, donc en voir une est contre-intuitif.
  • Lancer une NullReferenceException et provoquer une NullReferenceException produisent des exceptions sensiblement différentes (le code d'erreur est un moyen de voir la différence). C'est le cas de nombreuses exceptions lancées par le CLR.

Voir Quand peut-on attraper une StackOverflowException ? (un post que j'ai fait sur ce sujet).

  • Il est parfaitement légal d'appeler une méthode d'extension comme s'il s'agissait d'une méthode normale. Dans ce cas, je ne m'attendrais certainement pas à une NullReferenceException, mais plutôt à une ArgumentNullException.

0 votes

Comme je l'ai mentionné dans ma modification de l'article, c'est la raison pour laquelle je ne lève pas explicitement l'exception NullReferenceException, je laisse le CLR la lever.

1 votes

"Une référence nulle ne s'est pas produite". Si, elle s'est produite ; vous avez transmis une référence nulle et la méthode a essayé de la déréférencer.

0 votes

@piedar la méthode a essayé de le déréférencer, pas le runtime !

29voto

Jon Skeet Points 692016

En dehors de toutes les autres réponses (qui sont bonnes), je pense qu'il vaut la peine de regarder ce que fait Microsoft pour des raisons de cohérence... et les méthodes d'extension de Enumerable lèvent toutes ArgumentNullException pour autant que je puisse voir.

0 votes

Excellente idée, j'ai eu cette idée moi-même, mais je ne l'ai pas fait, je ne sais pas trop pourquoi ;-)

1 votes

C'est une technique utile que j'utilise moi-même très souvent. Cependant, il faut toujours garder à l'esprit que ce n'est pas parce que le FCL utilise une méthode particulière pour atteindre quelque chose que cette méthode est optimale ou correcte. Je recommande de considérer les méthodes du FCL comme des suggestions sur la manière de réaliser quelque chose, mais il faut comparer les mérites d'une méthode donnée à ceux d'autres méthodes avant de juger s'il s'agit du meilleur choix.

0 votes

Microsoft fait les deux, cela ne sert à rien.

8voto

casperOne Points 49736

Étant donné que les méthodes d'extension peuvent être utilisées en C# 2.0 et qu'elles peuvent être appelées comme des méthodes statiques (vous n'êtes pas obligé de les utiliser comme méthodes d'extension), vous devez utiliser ArgumentNullException.

Ce n'est pas parce qu'ils regardez comme des méthodes sur le type ne signifie pas qu'ils sont, ou sont toujours appelés comme un.

3voto

mquander Points 32650

Du point de vue de l'utilisateur, la méthode ressemble et se comporte comme une méthode d'instance. À sa place, je m'attendrais donc à voir apparaître une NullReferenceException.

Cela dit, je suggérerais de lancer l'un ou l'autre explicitement dans le code, au lieu de le faire par hasard comme dans votre premier exemple.

0 votes

Oui, j'ai pensé à lancer explicitement l'exception NullReferenceException, mais mon sentiment est que cela devrait être réservé au compilateur, mais vous pouvez très bien avoir raison.

2 votes

Du point de vue de l'utilisateur, une méthode d'extension peut être appelée aussi bien par extension que comme méthode statique.

0 votes

Je suis d'accord avec mqp et pas d'accord avec JaredPar : Du point de vue des utilisateurs, une méthode d'extension ne devrait jamais être appelée via l'interface statique et elle devrait toujours se comporter exactement comme la méthode d'instance. Par conséquent, je recommanderais de lancer une NullReferenceException (vous-même) sans aucun nom de paramètre. Ne permettez pas d'autres traitements d'erreurs (du premier paramètre) dans vos méthodes d'extension - bien que ce soit cool et souvent vu, par exemple retourner une chaîne vide lors de l'appel d'une méthode d'extension .Left(..) sur une chaîne non initialisée, mais totalement inattendu et non transparent.

2voto

Craig Stuntz Points 95965

ArgumentNullException. Il y a pas de l'obligation d'appeler les méthodes d'extension comme s'il s'agissait de méthodes d'instance. Vous pouvez les appeler comme s'il s'agissait de méthodes normales. L'exception NullReferenceException serait totalement incorrecte dans ce cas.

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