La distinction entre les types de référence et les types de valeur est fondamentalement un compromis de performance dans la conception du langage. Les types de référence ont des frais généraux sur la construction et la destruction et la collecte des ordures, car ils sont créés sur le tas. Les types de valeurs, d'autre part, ont des frais généraux sur les appels de méthode (si la taille des données est supérieure à un pointeur), car l'objet entier est copié plutôt qu'un simple pointeur. Étant donné que les chaînes peuvent être (et sont généralement) beaucoup plus grandes que la taille d'un pointeur, elles sont conçues comme types de référence. De plus, comme l'a souligné Servy, la taille d'un type de valeur doit être connue au moment de la compilation, ce qui n'est pas toujours le cas pour les chaînes.
La question de la mutabilité est une question distincte. Les types de référence et les types de valeur peuvent être mutables ou immuables. Les types de valeurs sont généralement immuables, car la sémantique des types de valeurs mutables peut prêter à confusion.
Les types de référence sont généralement modifiables, mais peuvent être conçus comme immuables si cela a du sens. Les chaînes sont définies comme immuables car elles permettent certaines optimisations. Par exemple, si le même littéral de chaîne se produit plusieurs fois dans le même programme (ce qui est assez courant), le compilateur peut réutiliser le même objet.
Alors pourquoi "==" est-il surchargé pour comparer les chaînes par texte? Parce que c'est la sémantique la plus utile. Si deux chaînes sont égales par du texte, elles peuvent ou non être la même référence d'objet en raison des optimisations. Donc, comparer des références est assez inutile, alors que comparer du texte est presque toujours ce que vous voulez.
De manière plus générale, Strings a ce qu'on appelle la sémantique des valeurs . Il s'agit d'un concept plus général que les types de valeur, qui est un détail d'implémentation spécifique à C #. Les types de valeur ont une sémantique de valeur, mais les types de référence peuvent également avoir une sémantique de valeur. Lorsqu'un type a une sémantique de valeur, vous ne pouvez pas vraiment dire si l'implémentation sous-jacente est un type de référence ou un type de valeur, vous pouvez donc considérer cela comme un détail d'implémentation.
is
côté les tests), la réponse est probablement "pour des raisons historiques". Les performances de copie ne peuvent pas être la raison, car il n'est pas nécessaire de copier physiquement des objets immuables. Il est maintenant impossible de changer sans casser le code qui utilise réellement desis
contrôles (ou des contraintes similaires).