Il y a beaucoup d'idées fausses ici, à la fois dans la question elle-même et de plusieurs réponses.
Permettez-moi de commencer par l'examen de la prémisse de la question. La question est "pourquoi avons-nous besoin de l' new
mot-clé en C#?" La motivation pour la question est ce fragment de C++:
MyClass object; // this will create object in memory
MyClass* object = new MyClass(); // this does same thing
Je reproche à cette question pour deux raisons.
Tout d'abord, ne pas faire la même chose en C++, donc la question est basée sur une mauvaise compréhension du langage C++. Il est très important de comprendre la différence entre ces deux choses en C++, donc si vous ne comprenez pas très clairement ce qu'est la différence, trouver un mentor qui peut vous enseigner comment savoir quelle est la différence, et lors de l'utilisation de chacun.
Deuxièmement, la question suppose -- erroné et que ces deux syntaxes de faire la même chose en C++, et puis, bizarrement, s'interroge: "pourquoi avons-nous besoin d' new
en C#?" Sûrement la bonne question à se poser compte tenu de cela, encore une fois, faux-présupposition est "pourquoi avons-nous besoin d' new
en C++?" Si ces deux syntaxes de faire la même chose, qu'ils ne sont pas, alors pourquoi deux syntaxes en premier lieu?
Donc, la question est à la fois basée sur une fausse prémisse, et la question sur le C# n'a pas fait suivre à partir de la -- incomprise-conception de C++.
C'est un gâchis. Nous allons jeter cette question et de poser quelques bonnes questions. Et posons-nous la question sur le C# qua C#, et non dans le contexte de la conception des décisions de C++.
Ce qui ne l' new X
opérateur de le faire en C#, où X est une classe ou d'un type struct? (Nous allons ignorer les délégués et les tableaux pour les fins de cette discussion.)
L'opérateur new:
- Les Causes d'une nouvelle instance d'un type donné d'être allouées; de nouvelles instances ont tous leurs champs initialisés aux valeurs par défaut.
- Les Causes d'un constructeur de ce type à être exécuté.
- Produit une référence à l'allocation d'un objet, si l'objet est un type de référence, ou de la valeur elle-même si l'objet est un type valeur.
Tout droit, j'entends déjà les objections de la part de C#, programmeurs, afin de laisser de la rejeter.
Objection: pas de nouvelle de stockage est alloué si le type est un type valeur, je vous entends dire. Ainsi, la spécification C# n'est pas d'accord avec vous. Quand vous dites
S s = new S(123);
pour certains type struct S
, la spec dit que temporaire de stockage est alloué sur le court-terme de la piscine, initialisé à ses valeurs par défaut, de l'exécution du constructeur avec this
ensemble pour se référer à la température de stockage, puis l'objet est copié à l' s
. Cependant, le compilateur est autorisé à utiliser une copie-élision de l'optimisation à condition qu'il puisse prouver qu'il est impossible pour l'optimisation de devenir observée dans un programme de sécurité. (Exercice: travailler dans quelles circonstances une copie élision ne peut pas être effectuée; donner un exemple d'un programme qui aurait un comportement différent si élision a été ou n'a pas été utilisé.)
Objection: une instance valide de type valeur peut être produit en utilisant default(S)
; aucun constructeur est appelé, me direz-vous. C'est correct. Je n'ai pas dit qu' new
est le seul moyen de créer une instance d'un type valeur.
En effet, pour une valeur type new S()
et default(S)
sont la même chose.
Objection: Est un constructeur réellement exécutées pour des situations comme new S()
, si non présent dans le code source en C# 6, je vous entends dire. C'est un "si un arbre tombe dans la forêt et personne ne l'entend, est-il un son?" question. Est-il une différence entre un appel à un constructeur qui ne fait rien, et aucun appel à tous? Ce n'est pas une question intéressante. Le compilateur est libre d'éluder les appels qu'il sait ne rien faire.
Supposons que nous avons une variable de type valeur. Doit-on initialiser la variable avec une instance produite par new
?
Pas de. Les Variables qui sont automatiquement initialisés, tels que les champs et les éléments du tableau, sera initialisé à la valeur par défaut-qui est, la valeur de la structure où tous les champs sont eux-mêmes à leurs valeurs par défaut.
Les paramètres formels sera initialisé avec l'argument, évidemment.
Les variables locales de type de valeur sont nécessaires pour être définitivement attribuées à quelque chose avant de les champs sont en lecture, mais il n'a pas besoin d'être un new
expression.
Donc, effectivement, les variables de type valeur sont automatiquement initialisés avec l'équivalent d' default(S)
, à moins qu'ils sont les habitants?
Oui.
Pourquoi ne pas faire la même chose pour les habitants?
L'utilisation d'un non initialisée local est fortement associée avec le code bogué. Le langage C# n'autorise pas cela parce que faire trouve des bugs.
Supposons que nous avons une variable de type référence. Doit-on initialiser S
avec une instance produite par new
?
Pas de. Automatique-initialisation des variables sera initialisé avec la valeur null. Les habitants peuvent être initialisés avec toute référence, y compris null
, et doit être définitivement attribuées avant de le lire.
Donc, effectivement, les variables de type référence sont automatiquement initialisés avec null
, à moins qu'ils sont les habitants?
Oui.
Pourquoi ne pas faire la même chose pour les habitants?
Même raison. Un probable bug.
Pourquoi ne pas initialiser automatiquement les variables de type référence, en appelant le constructeur par défaut automatiquement? C'est, pourquoi ne pas faire R r;
le même que R r = new R();
?
Eh bien, tout d'abord, de nombreux types n'ont pas de constructeur par défaut, ou d'ailleurs, tout accessible constructeur à tous. Deuxièmement, il semble bizarre d'avoir une règle pour un non initialisée local ou de terrain, une autre règle officielle, et encore une autre règle pour un élément de tableau. Troisièmement, la règle est très simple: une variable doit être initialisée à une valeur, cette valeur peut être tout ce que vous voulez; pourquoi l'hypothèse qu'une nouvelle instance est souhaitée justifiée? Il serait bizarre si ce
R r;
if (x) r = M(); else r = N();
causé un constructeur à exécuter pour initialiser r
.
En laissant de côté la sémantique de l' new
opérateur, pourquoi est-il nécessaire du point de vue syntaxique d'avoir un opérateur?
Il n'est pas. Il ya un certain nombre de syntaxes alternatives qui pourraient être grammatical. Le plus évident serait de simplement éliminer l' new
entièrement. Si nous avons une classe C
avec un constructeur C(int)
alors nous pourrions simplement dire C(123)
au lieu de new C(123)
. Ou nous pourrions utiliser une syntaxe comme celle - C.construct(123)
ou quelque chose de ce genre. Il y a un certain nombre de façons de le faire sans l' new
de l'opérateur.
Alors pourquoi l'avoir?
Tout d'abord, C# a été conçu pour être immédiatement familier pour les utilisateurs de C++, Java, JavaScript et d'autres langages utilisent new
nouvelle de stockage est en cours d'initialisation d'un objet.
Deuxièmement, le niveau de redondance syntaxique est hautement souhaitable. La création d'objet est particulière, nous souhaitons faire appel quand il arrive avec son propre opérateur.