web-dev-qa-db-fra.com

Impossible d'utiliser String.Empty comme valeur par défaut pour un paramètre facultatif

Je lis Effective C # par Bill Wagner. Dans Élément 14 - Minimiser la logique d'initialisation en double , il montre l'exemple suivant de l'utilisation de la nouvelle fonctionnalité de paramètres facultatifs dans un constructeur:

public MyClass(int initialCount = 0, string name = "")

Notez qu'il a utilisé "" Au lieu de string.Empty.
Il commente:

Vous remarquerez [dans un exemple ci-dessus] que le deuxième constructeur a spécifié "" pour la valeur par défaut sur le paramètre nom , plutôt que le plus habituel string.Empty. En effet, string.Empty N'est pas une constante de compilation. Il s'agit d'une propriété statique définie dans la classe de chaîne. Étant donné qu'il ne s'agit pas d'une constante de compilation, vous ne pouvez pas l'utiliser pour la valeur par défaut d'un paramètre.

Si nous ne pouvons pas utiliser la statique string.Empty Dans toutes les situations, cela ne va-t-il pas à l'encontre de son objectif? Je pensais que nous l'utiliserions pour être sûr d'avoir un moyen indépendant du système de faire référence à la chaîne vide. Ma compréhension est-elle mauvaise? Merci.

MISE À JOUR
Juste un commentaire de suivi. Selon MSDN:

Chaque paramètre facultatif a une valeur par défaut dans le cadre de sa définition. Si aucun argument n'est envoyé pour ce paramètre, la valeur par défaut est utilisée. Les valeurs par défaut doivent être des constantes.

Ensuite, nous ne pourrons pas non plus utiliser System.Environment.NewLine, Ni utiliser de nouveaux objets instanciés comme valeurs par défaut. Je n'ai pas encore utilisé VS2010, et c'est décevant!

86
Mikeyg36

Depuis le compilateur C # 2.0, il y a très peu d'intérêt à String.Empty de toute façon, et en fait dans de nombreux cas, c'est une pessimisation, car le compilateur peut incorporer quelques références à "" mais ne peut pas faire de même avec String.Empty.

En C # 1.1, il était utile d'éviter de créer de nombreux objets indépendants contenant tous la chaîne vide, mais ces jours sont révolus. "" fonctionne très bien.

59
Andy Mortimer

Rien ne vous empêche de définir votre propre constante pour la chaîne vide si vous voulez vraiment l'utiliser comme valeur de paramètre facultative:

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[En passant, une raison de préférer String.Empty plus de "" en général, ce qui n'a pas été mentionné dans les autres réponses, est qu'il existe divers caractères Unicode (menuisiers de largeur nulle, etc.) qui sont effectivement invisibles à l'œil nu. Donc, quelque chose qui ressemble à "" n'est pas nécessairement la chaîne vide, alors qu'avec String.Empty vous savez exactement ce que vous utilisez. Je reconnais que ce n'est pas une source courante de bugs, mais c'est possible.]

52
Matthew Strawbridge

De la question d'origine:

Je pensais que nous l'utiliserions pour être sûr d'avoir un moyen indépendant du système de faire référence à la chaîne vide.

De quelle manière la chaîne vide peut-elle varier d'un système à l'autre? C'est toujours une chaîne sans caractères! Je serais vraiment effrayé si jamais je trouvais une implémentation où string.Empty == "" retourné faux :) C'est pas identique à quelque chose comme Environment.NewLine.

Du billet de prime de Counter Terrorist:

Je veux que String.Empty puisse être utilisé comme paramètre par défaut dans la prochaine version C #. :RÉ

Eh bien, cela ne se produira certainement pas.

Bien que j'aurais personnellement aimé un mécanisme par défaut très différent également, la façon dont les paramètres facultatifs fonctionnent est dans .NET depuis le début - et cela signifie toujours l'incorporation d'une constante dans les métadonnées, de sorte que le code appelant puisse copier cette constante dans l'appel site si aucun argument correspondant n'est fourni.

Avec string.Empty c'est vraiment inutile - en utilisant "" fera ce que vous voulez; est-ce que pénible d'utiliser la chaîne littérale? (J'utilise le littéral partout - je n'utilise jamais string.Empty - mais c'est un argument différent.)

C'est ce qui me surprend à propos de cette question - la plainte tourne autour de quelque chose qui ne le fait pas cause en fait un vrai problème. C'est plus important dans les cas où vous souhaitez que la valeur par défaut soit calculée au moment de l'exécution, car elle peut en fait varier. Par exemple, je pourrais imaginer des cas dans lesquels vous souhaitez pouvoir appeler une méthode avec un paramètre DateTime et le définir par défaut sur "l'heure actuelle". Pour le moment, la seule solution de contournement vaguement élégante que je connaisse est:

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

... mais ce n'est pas toujours approprié.

En conclusion:

  • Je doute fort que cela fasse jamais partie de C #
  • Pour string.Empty c'est inutile de toute façon
  • Pour les autres valeurs qui ont vraiment pas ont toujours la même valeur, c'est vraiment peut être une douleur
24
Jon Skeet

Je n'utilise jamais de chaîne, vide, je n'en vois pas l'intérêt. Peut-être que cela rend plus facile pour les gens qui sont vraiment nouveaux dans la programmation, mais je doute que ce soit utile même pour cela.

7
Hans Olsson

Je pense que l'idée derrière string est vide, elle améliore la lisibilité. Ce n'est pas comme la nouvelle ligne où il y a une différence entre la façon dont il est représenté sur différentes plates-formes. C'est dommage qu'il ne puisse pas être utilisé dans un paramètre par défaut. Cependant, cela ne causera aucun problème si vous portez entre Windows et quelque chose comme Mono sur Linux.

4
Tom Cabanski

En tant que FYI, il semble que la même contrainte soit imposée aux valeurs transmises aux constructeurs d'attributs - elles doivent être constantes. Puisque string.empty est défini comme:

public static readonly string Empty

plutôt qu'une constante réelle, elle ne peut pas être utilisée.

3
Shawn Eavis

J'utilise string.Empty uniquement pour la lisibilité.

Si quelqu'un d'autre a besoin de lire/modifier mon code plus tard, il sait que je voulais vérifier ou définir quelque chose sur une chaîne vide. Utiliser simplement "" peut parfois provoquer des bugs et de la confusion car j'ai peut-être juste oublié d'y mettre la chaîne que je voulais.

Par exemple:

if(someString == string.Empty)
{

}

contre

if(someString == "")
{

}

La première instruction if me semble tellement plus délibérée et lisible. Parce que ce n'est qu'une préférence, je ne vois vraiment pas le train-smash d'avoir à utiliser "" au lieu de string.Empty.

1
lukejkw