Question

Prenez l'extrait suivant:

List<int> distances = new List<int>();

La redondance était-elle destinée par les concepteurs de langage? Si oui, pourquoi?

Était-ce utile?

La solution

La raison pour laquelle le code semble être redondant est que, pour un programmeur débutant, il semble définir deux fois la même chose. Mais ce n'est pas ce que le code fait. Il définit deux choses distinctes qui se trouvent être du même type. Il définit ce qui suit:

  1. Une variable nommée distances de type List<int>.
  2. Un objet sur le tas de type <=>.

Considérez ce qui suit:

Person[] coworkers = new Employee[20];

Ici, la non-redondance est plus claire, car la variable et l'objet alloué sont de deux types différents (une situation qui est légale si le type de l'objet & # 8217; s dérive de ou implémente la variable & #. 8217; type)).

Autres conseils

Qu'est-ce qui compte à ce sujet?

List<int> listOfInts = new List<int>():

Traduit en anglais: (EDIT, nettoyé un peu pour clarification)

  • Créez un pointeur de type List < int > et nommez-la listofInts.
  • listOfInts est maintenant créé, mais c’est juste un pointeur de référence pointant vers nulle part (null)
  • Maintenant, créez un objet de type List < int > sur le tas et renvoyez le pointeur sur listOfInts.
  • listOfInts pointe vers une liste < int > sur le tas.

Pas vraiment bavard quand on pense à ce que ça fait.

Bien sûr, il existe une alternative:

var listOfInts = new List<int>();

Nous utilisons ici l'inférence de type de C #, car vous l'attribuez immédiatement, C # peut déterminer le type que vous voulez créer par l'objet que vous venez de créer dans le tas.

Pour bien comprendre comment le CLR gère les types, je recommande de lire CLR via C # .

Vous pouvez toujours dire:

 var distances = new List<int>();

Comme d'autres l'ont déjà dit: var supprime la redondance, mais cela a des conséquences de maintenance négatives potentielles. Je dirais que cela a également des conséquences positives sur la maintenance.

Heureusement, Eric Lippert en parle beaucoup plus éloquemment que moi: http://csharpindepth.com/ViewNote.aspx?NoteID=63 http://csharpindepth.com/ViewNote.aspx?NoteID=61

Parce que la déclaration d'un type n'a rien à voir avec son initialisation.

Je peux déclarer

List<int> foo; 

et laissez-le être initialisé plus tard. Où est la redondance alors? Peut-être qu'il reçoit la valeur d'une autre fonction telle que BuildList ().

Comme d'autres l'ont mentionné, le nouveau mot-clé var vous permet de contourner ce problème, mais vous devez initialiser la variable lors de la déclaration pour que le compilateur puisse déterminer son type.

Au lieu de penser qu'elle est redondante, considérez cette construction comme une fonctionnalité vous permettant de sauvegarder une ligne.

au lieu d'avoir

Lister les distances; distances = new List ();

c # vous permet de les mettre sur une seule ligne.

Une ligne indique & "J'utiliserai une variable appelée distances , et ce sera du type List. &"; Une autre ligne indique & "Allouer une nouvelle liste et appeler le constructeur sans paramètre &";

.

Est-ce trop redondant? Peut-être. le faire de cette façon vous donne certaines choses, même si

1 . Sépare la déclaration de variable de l'allocation d'objet. Permettre:

IEnumerable<int> distances = new List<int>();
// or more likely...
IEnumerable<int> distances = GetList();

2. Il permet au compilateur de procéder à une vérification plus poussée des types statiques - ce qui provoque des erreurs du compilateur lorsque vos déclarations ne correspondent pas aux affectations, plutôt que des erreurs d'exécution.

Ces deux éléments sont-ils nécessaires pour écrire un logiciel? Non, beaucoup de langues ne le font pas et / ou diffèrent sur de nombreux autres points.

& "Docteur! ça fait mal quand je fais ça! " - & "Ne faites plus ça &";

Si vous constatez que vous n’avez pas besoin ou que vous ne voulez pas ce que c # vous donne, essayez d’autres langues. Même si vous ne les utilisez pas, connaître d’autres personnes peut vous donner un énorme coup de pouce dans votre façon d’aborder les problèmes. Si vous en utilisez un, tant mieux!

Dans tous les cas, vous pouvez trouver suffisamment de perspective pour vous permettre de dire & "; je n'ai pas besoin de la vérification de type statique stricte imposée par le compilateur c #. Je vais utiliser python & ";" Plutôt que de considérer c # comme trop redondant.

Peut aussi faire:

var distances = new List<int>();

Les améliorations apportées au compilateur pour C # 3.0 (ce qui correspond à .Net 3.5) éliminent un peu ce genre de chose. Donc, votre code peut maintenant être écrit comme:

var distances = new List<int>();

Le compilateur mis à jour est bien meilleur pour déterminer les types en fonction des informations supplémentaires contenues dans la déclaration. Cela signifie qu'il y a moins d'instances dans lesquelles vous devez spécifier un type pour une affectation ou dans le cadre d'un générique.

Cela étant dit, certains domaines pourraient encore être améliorés. Une partie de cela est une API et une autre est simplement due aux restrictions du typage fort.

La redondance n'était pas prévue en soi, mais était un effet secondaire du fait que toutes les variables et tous les champs devaient avoir une déclaration de type. Lorsque vous prenez en compte le fait que toutes les instanciations d'objet mentionnent également le nom du type dans une nouvelle expression, vous obtenez des instructions redondantes.

Maintenant, avec l'inférence de type utilisant le mot clé var , cette redondance peut être éliminée. Le compilateur est assez intelligent pour le comprendre. Le prochain C ++ a également un mot clé auto qui fait la même chose.

La principale raison pour laquelle ils ont introduit var était cependant pour les types anonymes, qui n'ont pas de nom:

var x = new {Foo = Bar, Number = 1};

Ce n'est que & "; redondant &"; si vous le comparez à des langages typés dynamiquement. C'est utile pour le polymorphisme et la recherche de bogues au moment de la compilation. De plus, cela rend le code de complétion automatique / intellisense plus facile pour votre IDE (si vous en utilisez un).

Un artefact historique de la syntaxe statique de typage / C; comparez l'exemple Ruby:

distances = []

C # devient définitivement moins bavard après l’ajout du support fonctionnel.

Utilisez var si le type est évident pour le lecteur.

//Use var here
var names = new List<string>();

//but not here
List<string> names = GetNames();

Des microsofts Guide de programmation C #

  

Le mot-clé var peut également être utile   quand le type spécifique de la variable   est fastidieux de taper sur le clavier, ou   est évident, ou n'ajoute pas à la   lisibilité du code

Votre exemple particulier est certes un peu prolixe mais, dans la plupart des cas, C # est plutôt maigre.

Je préférerais de beaucoup cela (C #)

int i;

à ceci (VB.NET)

Dim i as Integer

Maintenant, l’exemple particulier que vous avez choisi est quelque chose à propos de .NET en général qui est un peu long, mais je ne pense pas que ce soit la faute de C #. Peut-être que la question devrait être reformulée & «Pourquoi le code .NET est-il si prolixe? &«;

Je vois un autre problème avec l'utilisation de var pour la paresse comme ça

var names = new List<string>();

Si vous utilisez var, la variable nommée " names " est tapé comme List<string>, mais vous n'utiliserez finalement que l'une des interfaces héritées par List<T>.

IList<string> = new List<string>();
ICollection<string> = new List<string>();
IEnumerable<string> = new List<string>();

Vous pouvez utiliser automatiquement tout ce que vous voulez, mais pouvez-vous indiquer quelle interface vous vouliez utiliser au moment de la rédaction du code?

Le mot-clé var n'améliore pas la lisibilité dans cet exemple.

Dans de nombreuses réponses à cette question, les auteurs pensent comme des compilateurs ou des apologistes. Une règle importante de la bonne programmation est Ne vous répétez pas!

Éviter cette répétition inutile est un objectif de conception explicite de Go, par exemple:

  

Le bégaiement (foo.Foo* myFoo = new(foo.Foo)) est réduit par une simple dérivation de type à l'aide de la construction := declare-and-initialize.

Parce que nous sommes accros aux compilateurs et aux erreurs de compilateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top