64 votes

Dois-je lancer l'exception ArgumentNullException si une chaîne de caractères est vide ?

Je travaille sur une méthode qui fait quelque chose avec un paramètre de type chaîne. Une valeur valide pour le paramètre string est tout autre que null ou string.Empty. Mon code ressemble donc à ceci.

private void SomeMethod(string someArgument)
{
    if(string.IsNullOrEmpty(someArgument))
        throw new ArgumentNullException("someArgument");

    // do some work
}

Rien de bien excitant. Ma question est la suivante : est-il possible de lancer une exception ArgumentNullException même si la chaîne est égale à string.Empty ? Parce que techniquement, elle n'est pas nulle. Si vous pensez que l'exception ArgumentNullException ne devrait pas être levée, quelle exception devrait être levée ?

2 votes

Lancer une exception ArgumentNullException lorsque la chaîne de caractères est "" est trompeur.

0 votes

Je suis d'accord, hélas la raison pour laquelle je l'ai fait de cette façon est la réponse donnée par "Joe", c'est utilisé comme ça dans le code du .net framework.

47voto

Ahmad Mageed Points 44495

ArgumentException devrait être lancée pour le String.Empty cas. Cela indiquerait un problème autre que le fait qu'il soit nul. Pour éviter un NullReferenceException Je vérifie d'abord s'il y a des nullités, puis je coupe et vérifie s'il y a des vides pour éviter que des espaces blancs ne passent.

private void SomeMethod(string someArgument)
{
    if(someArgument == null)
        throw new ArgumentNullException("someArgument");

    if (someArgument.Trim() == String.Empty)
        throw new ArgumentException("Input cannot be empty", "someArgument");

    // do some work
}

À partir de la version 4.0 de .NET, vous pouvez utiliser la fonction String.IsNullOrWhiteSpace pour effectuer ces vérifications en une seule fois. En procédant ainsi, vous renoncez à la possibilité de spécifier un type d'exception granulaire, et j'opterais donc pour la méthode ArgumentException et mettre à jour le message en conséquence.

0 votes

J'utilise C# 2.0, la seule référence à InvalidArgumentException se trouve dans l'espace de noms Microsoft.SqlServer.Management.Common, est-ce que vous recommandez ou suggérez-vous que je crée ma propre classe InvalidArgumentException ?

0 votes

@Keith : vous avez raison, c'est mon erreur. Vous pourriez écrire le vôtre si vous en avez envie ou utiliser l'exception ArgumentException fournie par le framework. Je vais éditer pour refléter le nom correct.

4 votes

Le constructeur d'ArgumentException ne prend pas de paramètre "paramName" comme ArgumentNullException. Ainsi, "throw new ArgumentException("paramName")" est potentiellement déroutant, car il ne donne aucune indication sur ce qui ne va pas avec l'argument. Vous devriez fournir un argument "message" du type ("someArgument may not be an empty string"). Et dans une application internationale, ce message devrait être localisé. Par conséquent, je ne me donnerais tout ce mal que s'il y a vraiment besoin de distinguer le cas nul du cas de la chaîne vide.

5voto

Ronald Wildenberg Points 18258

Vous devriez lancer un ArgumentException si une chaîne vide n'est pas une entrée acceptée pour votre méthode. Cela peut être très déroutant pour les clients si vous lancez un message de type ArgumentNullException alors qu'ils n'ont pas fourni null argument.

Il s'agit simplement d'un autre cas d'utilisation. Vous pouvez également avoir des méthodes qui n'acceptent pas les valeurs d'entrée nulles mais qui acceptent les chaînes vides. Il est important d'être cohérent dans l'ensemble de votre application.

0 votes

Je pensais à l'exception ArgumentOutOfRangeException, mais elle est peut-être utilisée pour les exceptions de plage d'index de tableau.

0 votes

Pour les exceptions relatives à l'indice du tableau, on utilise IndexOutOfRangeException. Vous ne devez utiliser ArgumentOutOfRangeException que si votre méthode est documentée pour n'accepter qu'une collection spécifique de chaînes de caractères (par exemple : "abc", "def", "ghi" sont les seules entrées acceptées).

0 votes

La propre documentation de Microsoft semble fournir des conseils contradictoires sur le sujet IndexOutOfRangeException/ArgumentOutOfRangeException. docs.microsoft.com/fr/us/dotnet/api/ C'est peut-être là qu'ils se dirigent, mais je suis plutôt d'accord avec @ronald-wildenberg sur leur utilisation

4voto

Marcel Jackwerth Points 20632

En tenant compte de tout ce qui a été dit (Joe / Ahmad Mageed), je créerais alors une exception pour ce cas.

class ArgumentNullOrEmptyException : ArgumentNullException

16 votes

Ne serait-il pas préférable de dériver de ArgumentException ? En POO, dire que "A ou B" est un "A" ne semble pas correct.

0 votes

@dcstraw ArgumentNullException dérive de ArgumentException. Dans ce cas, je pense qu'il est préférable que ArgumentNullOrEmptyException dérive de ArgumentNullException.

0 votes

Je pense également que son nom devrait être StringArgumentNullOrEmptyException car elle n'a de sens que pour les arguments de type chaîne.

2voto

Joe Points 60749

ArgumentNullException est parfois utilisé dans le .NET Framework pour le cas String.IsNullOrEmpty - un exemple est le suivant System.Windows.Forms.Clipboard.SetText .

Je pense donc qu'il est raisonnable de faire la même chose dans votre code, à moins qu'il n'y ait un réel intérêt à distinguer les deux cas.

Notez que cette exception et les autres exceptions dérivées de ArgumentException indiquent généralement une erreur de programmation, et doivent donc fournir les informations nécessaires pour aider un développeur à diagnostiquer le problème. Personnellement, je pense qu'il est peu probable qu'un développeur trouve déroutant que vous utilisiez ArgumentNullException pour un argument de type chaîne vide, surtout si vous documentez ce comportement comme dans l'exemple ci-dessous.

/// <summary>
/// ... description of method ...
/// </summary>
/// <param name="someArgument">... description ...</param>
/// <exception cref="ArgumentNullException">someArgument is a null reference or Empty.</exception>
public void SomeMethod(string someArgument)
{
   ...
}

4 votes

Je ne me tournerais pas vers Windows Forms pour trouver des exemples des dernières bonnes pratiques en matière de code .NET Framework. J'ai pu trouver rapidement un contre-exemple dans File.Copy(string, string), qui lève l'exception ArgumentNullException pour null et ArgumentException pour empty.

0voto

Kyle Rozendo Points 15606

Cela dépend des circonstances.

La question qui se pose est la suivante : s'agit-il vraiment d'une erreur ? Je veux dire par là que vous siempre attendre une valeur ? Si c'est le cas, votre meilleure option est de créer votre propre code d'accès. Exception peut-être comme ça :

class StringEmptyOrNullException : Exception
{
}

Vous pouvez également y ajouter vos propres constructeurs, des informations supplémentaires, etc.

Toutefois, s'il ne s'agit pas d'un événement "exceptionnel" dans votre programme, il serait probablement plus judicieux de renvoyer la méthode null et de la gérer à partir de là. N'oubliez pas, Exception sont destinés à des conditions exceptionnelles.

J'espère que cela vous aidera,

Kyle

1 votes

Si vous hacer créez votre propre exception, elle doit dériver de ArgumentException plutôt que de Exception.

0 votes

Cela dépend du contexte, mais dans ce contexte, oui. Si vous voulez l'utiliser dans d'autres endroits, vous devez le rendre plus générique. Par exemple, si vous avez une méthode qui génère une chaîne qui ne doit pas être vide, ArgumentException ne sera pas le meilleur choix. Ainsi, en fonction de l'utilisation que vous en faites, et du contexte dans lequel elle est utilisée, vous déciderez alors de quoi hériter.

0 votes

Je pense qu'il s'agit de deux situations différentes - une méthode générant une chaîne de caractères et un argument passé à une méthode - et je préférerais avoir deux types d'exception différents. Il est préférable d'être verbeux plutôt que de regrouper plusieurs types d'erreurs dans une seule exception.

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