Dans .Net, pourquoi String.Empty est-il en lecture seule au lieu d'une constante? Je me demande simplement si quelqu'un sait quel était le raisonnement derrière cette décision.
Dans .Net, pourquoi String.Empty est-il en lecture seule au lieu d'une constante? Je me demande simplement si quelqu'un sait quel était le raisonnement derrière cette décision.
Réponses:
La raison qui static readonly
est utilisée à la place de const
est due à une utilisation avec du code non managé, comme indiqué par Microsoft ici dans la version Shared Source Common Language Infrastructure 2.0 . Le fichier à consulter est sscli20\clr\src\bcl\system\string.cs
.
La constante Empty contient la valeur de chaîne vide. Nous devons appeler le constructeur String afin que le compilateur ne le marque pas comme un littéral.
Marquer cela comme un littéral signifierait qu'il n'apparaît pas comme un champ auquel nous pouvons accéder à partir de natif.
J'ai trouvé ces informations dans cet article pratique sur CodeProject .
String.Empty
plus utiliser pour cette seule raison.
Je pense qu'il y a beaucoup de confusion et de mauvaises réponses ici.
Tout d'abord, les const
champs sont des static
membres ( pas des membres d'instance ).
Consultez la section 10.4 Constantes de la spécification du langage C #.
Même si les constantes sont considérées comme des membres statiques, une déclaration de constante ne nécessite ni n'autorise un modificateur statique.
Si les public const
membres sont statiques, on ne peut pas considérer qu'une constante créera un nouvel objet.
Compte tenu de cela, les lignes de code suivantes font exactement la même chose en ce qui concerne la création d'un nouvel objet.
public static readonly string Empty = "";
public const string Empty = "";
Voici une note de Microsoft qui explique la différence entre les 2:
Le mot-clé readonly est différent du mot-clé const. Un champ const ne peut être initialisé qu'à la déclaration du champ. Un champ en lecture seule peut être initialisé au niveau de la déclaration ou dans un constructeur. Par conséquent, les champs en lecture seule peuvent avoir des valeurs différentes selon le constructeur utilisé. De plus, alors qu'un champ const est une constante de compilation, le champ readonly peut être utilisé pour les constantes d'exécution, ...
Je trouve donc que la seule réponse plausible ici est celle de Jeff Yates.
const string
et static readonly string
je fais la même chose. Les valeurs const sont remplacées dans le code lié tandis que les valeurs statiques en lecture seule sont référencées. Si vous avez un const
dans la bibliothèque A qui est utilisé par la bibliothèque B, la bibliothèque B remplacera toutes les références à cette const
variable par sa valeur littérale; si cette variable l'était à la static readonly
place, elle serait référencée et sa valeur déterminée au moment de l'exécution.
String.Empty read only instead of a constant?
Si vous rendez une chaîne constante , le compilateur est remplacé par la chaîne en fait partout où vous l'appelez et vous remplissez votre code avec la même chaîne partout et lorsque le code s'exécute, il est également nécessaire de lire encore et encore cette chaîne à partir de la mémoire différente Les données.
Si vous laissez votre chaîne en lecture seule à un seul endroit comme c'est le cas String.Empty
, le programme ne conserve la même chaîne qu'à un seul endroit et la lit ou y fait référence - en gardant les données en mémoire au minimum.
De plus, si vous compilez une dll en utilisant le String.Empty comme const, et pour une raison quelconque le changement de String.Empty, alors la dll compilée ne fonctionnera plus de la même manière, car le cost
code interne permet de conserver une copie de la chaîne à chaque appel.
Voir ce code par exemple:
public class OneName
{
const string cConst = "constant string";
static string cStatic = "static string";
readonly string cReadOnly = "read only string";
protected void Fun()
{
string cAddThemAll ;
cAddThemAll = cConst;
cAddThemAll = cStatic ;
cAddThemAll = cReadOnly;
}
}
sera venu par le compilateur comme:
public class OneName
{
// note that the const exist also here !
private const string cConst = "constant string";
private readonly string cReadOnly;
private static string cStatic;
static OneName()
{
cStatic = "static string";
}
public OneName()
{
this.cReadOnly = "read only string";
}
protected void Fun()
{
string cAddThemAll ;
// look here, will replace the const string everywhere is finds it.
cAddThemAll = "constant string";
cAddThemAll = cStatic;
// but the read only will only get it from "one place".
cAddThemAll = this.cReadOnly;
}
}
et l'appel à l'assemblée
cAddThemAll = cConst;
0000003e mov eax,dword ptr ds:[09379C0Ch]
00000044 mov dword ptr [ebp-44h],eax
cAddThemAll = cStatic ;
00000047 mov eax,dword ptr ds:[094E8C44h]
0000004c mov dword ptr [ebp-44h],eax
cAddThemAll = cReadOnly;
0000004f mov eax,dword ptr [ebp-3Ch]
00000052 mov eax,dword ptr [eax+0000017Ch]
00000058 mov dword ptr [ebp-44h],eax
Edit: faute de frappe corrigée
Cette réponse existe à des fins historiques.
Initialement:
Parce que String
c'est une classe et ne peut donc pas être une constante.
Discussion approfondie:
Un grand nombre de dialogues utiles ont été élaborés pour vérifier cette réponse, et plutôt que de la supprimer, ce contenu est reproduit directement:
Dans .NET, (contrairement à Java), la chaîne et la chaîne sont exactement les mêmes. Et oui, vous pouvez avoir des constantes littérales de chaîne dans .NET - DrJokepu 3 février 09 à 16:57
Êtes-vous en train de dire qu'une classe ne peut pas avoir de constantes? - StingyJack 3 février 09 à 16:58
Oui, les objets doivent être utilisés en lecture seule. Seules les structures peuvent faire des constantes. Je pense que lorsque vous utilisez à la
string
place duString
compilateur, vous changez le const en lecture seule pour vous. Tout à voir avec la satisfaction des programmeurs C. - Garry Shutler le 3 février 2009 à 16 h 59tvanfosson vient de l'expliquer un peu plus verbeux. "X ne peut pas être une constante, car le Y contenant est une classe" était juste un peu trop sans contexte;) - Leonidas 3 février 09 à 17:01
string.Empty est une propriété statique qui renvoie une instance de la classe String, à savoir la chaîne vide, pas la classe chaîne elle-même. - tvanfosson le 3 février 2009 à 17:01
Empty est une instance en lecture seule (ce n'est pas une propriété) de la classe String. - senfo 3 février 09 à 17:02
Tête qui fait mal. Je pense toujours que j'ai raison, mais maintenant je suis moins sûr. Recherche requise ce soir! - Garry Shutler 3 février 2009 à 17:07
La chaîne vide est une instance de la classe de chaînes. Empty est un champ statique (pas une propriété, je suis corrigé) sur la classe String. Fondamentalement, la différence entre un pointeur et la chose vers laquelle il pointe. Si ce n'était pas en lecture seule, nous pourrions changer à quelle instance le champ Empty se réfère. - tvanfosson le 3 février 2009 à 17:07
Garry, tu n'as pas besoin de faire de recherches. Pensez-y. String est une classe. Empty est une instance d'une chaîne. - senfo le 3 février 09 à 17:12
Il y a quelque chose que je ne comprends pas tout à fait: comment diable le constructeur statique de la classe String peut-il créer une instance de la classe String? N'est-ce pas une sorte de scénario «poulet ou œuf»? - DrJokepu 3 février 09 à 17:12 5
Cette réponse serait correcte pour presque toutes les autres classes sauf System.String. .NET fait beaucoup de casse spéciale de performance pour les chaînes, et l'un d'eux est que vous POUVEZ avoir des constantes de chaîne, essayez-le. Dans ce cas, Jeff Yates a la bonne réponse. - Joel Mueller 3 février 09 à 19:25
Comme décrit au §7.18, une expression constante est une expression qui peut être entièrement évaluée au moment de la compilation. Étant donné que la seule façon de créer une valeur non nulle d'un type de référence autre que chaîne est d'appliquer le nouvel opérateur, et puisque le nouvel opérateur n'est pas autorisé dans une expression constante, la seule valeur possible pour les constantes de types référence autre que string est nul. Les deux commentaires précédents ont été tirés directement de la spécification du langage C # et réitèrent ce que Joel Mueller a mentionné. - senfo 4 février 09 à 15:05 5