web-dev-qa-db-fra.com

Pourquoi les noms de membres C # ne peuvent-ils pas être identiques au nom de type qui les entoure?

En C #, le code suivant ne se compile pas:

class Foo {

    public string Foo;

}

La question est: pourquoi?

Plus exactement, je comprends que cela ne compile pas parce que (je cite):

les noms des membres ne peuvent pas être les mêmes que leur type englobant

OK bien. Je comprends cela, je ne le ferai plus, je le promets.

Mais je ne comprends vraiment pas pourquoi le compilateur refuse de prendre n'importe quel champ ayant le même nom qu'un type englobant. Quel est le problème sous-jacent qui m'empêche de le faire?

52
Vivien Barousse

À strictement parler, il s'agit d'une limitation imposée par C #, très probablement pour la commodité de la syntaxe. Un constructeur a un corps de méthode, mais son entrée de membre dans IL est désignée comme ".ctor" et il a des métadonnées légèrement différentes d'une méthode normale (dans les classes de réflexion, ConstructorInfo dérive de MethodBase, pas MethodInfo.) Je ne crois pas il y a une limitation .NET qui empêche de créer un membre (ou même une méthode) avec le même nom que le type externe, même si je ne l'ai pas essayé.


J'étais curieux, j'ai donc confirmé qu'il ne s'agissait pas d'une limitation .NET. Créez la classe suivante dans VB:

Public Class Class1
    Public Sub Class1()

    End Sub
End Class

En C #, vous le référencez comme:

var class1 = new Class1();
class1.Class1();
49
Dan Bryant

Parce que Foo est réservé comme nom du constructeur.

Donc, si votre code était autorisé - comment appelleriez-vous le constructeur?

Même s'il était possible de le faire en traitant le constructeur comme un cas spécial et en introduisant de nouvelles règles dans la liaison méthode/membre - serait-ce une bonne idée? Cela conduirait inévitablement à la confusion à un moment donné.

19
James Gaunt

Parce que le nom du membre se heurte au nom du constructeur de la classe?

2
winwaed

Il y a une bonne façon de le faire et une mauvaise façon de le faire.

Pourquoi C # ne le permet-il pas?

Parce que cela n'a pas de raison de le faire. Pourquoi voudriez-vous créer une telle confusion dans votre vie.

Je pense que le CLR le permet, comme le prouve un autre article avec un exemple sur vb.net et il ne devrait pas être restreint, mais je ne voudrais pas créer une application basée sur les mêmes règles que le CLR. L'abstraction rend le code plus clair . Je pense que l'argument fonctionne au même niveau que l'héritage multiple. Oui, cela peut être fait dans certaines langues, mais cela crée de la confusion. Ma réponse serait donc de réduire l'ambiguïté et la confusion et est basée sur l'analyseur/compilateur c #. Un choix de design par l'équipe C #.

0
WeNeedAnswers