2010-11-01 5 views
44

En C#, el siguiente código no se compila:¿Por qué los nombres de miembros de C# no pueden ser iguales al nombre de tipo adjunto?

class Foo { 

    public string Foo; 

} 

La pregunta es: ¿por qué?

Más exactamente, entiendo que esto no se compila porque (cito): nombres

miembros no pueden ser el mismo que su tipo envolvente

Ok, está bien. Entiendo eso, no lo haré de nuevo, lo prometo.

Pero realmente no entiendo por qué el compilador se niega a tomar cualquier campo que tenga el mismo nombre que un tipo adjunto. ¿Cuál es el problema subyacente que me impide hacer eso?

Respuesta

43

en sentido estricto, esto es una limitación impuesta por C#, más probable es que por conveniencia de la sintaxis. Un constructor tiene un cuerpo de método, pero su entrada miembro en IL se denota como ".ctor" y tiene metadatos ligeramente diferentes a los de un método normal (En las clases de Reflexión, ConstructorInfo deriva de MethodBase, no de MethodInfo.) No creo hay una limitación .NET que impide crear un miembro (o incluso un método) con el mismo nombre que el tipo externo, aunque no lo he intentado.


Tenía curiosidad, así que confirmó que no es una limitación de .NET. Crear la siguiente clase en VB:

Public Class Class1 
    Public Sub Class1() 

    End Sub 
End Class 

En C#, se hace referencia a ella como:

var class1 = new Class1(); 
class1.Class1(); 
+1

Esta es probablemente la mejor y más completa respuesta aquí. En VB (creo que acabo de vomitar un poco en la boca), el ctor es Sub New() ... –

+0

¿Quiere decir "evita crear un miembro" de la forma en que lo describe en la pregunta? Sí, esa es toda la razón de esta pregunta. Si te refieres a 'cadena pública Foo {get; set;} public void Foo() {}' entonces no, eso tampoco está permitido. – jcolebrand

+1

La pregunta es si solo C# no lo permite o si el sistema de tipos .net no lo permite. Y supongo que es solo C#. – CodesInChaos

18

Porque Foo está reservado como el nombre del constructor.

lo tanto, si se le permitió su código - lo que habría que llamar al constructor?

Incluso si era posible hacer esto mediante el tratamiento del constructor como un caso especial y la introducción de nuevas reglas en el método/miembro de unión - ¿sería una buena idea? Inevitablemente conduciría a la confusión en algún momento.

+3

Pero el constructor no es un método ni nada, no debería interferir con el resto del código. –

+8

El constructor es un método.¿Por qué crees que no es así? P.ej. puede llamarlo desde un constructor en un objeto derivado. –

+1

@James Gaunt, porque no devuelve nada, es un [constructor] (http://en.wikipedia.org/wiki/Constructor_%28object-oriented_programming%29). No estoy seguro de cómo funciona en C#, pero en java un constructor no tiene nada que ver con un método, excepto que es un bloque de código. ¿No lo llamas con 'base()'? Entonces no debería ser un problema aquí también. –

2

Debido a los enfrentamientos Nombre de usuario con el nombre del constructor de la clase?

0

Hay una manera correcta de hacerlo y una manera incorrecta de hacerlo.

¿Por qué no en C# permite?

Porque no razón para hacerlo. ¿Por qué querrías crear tal confusión en tu vida?

Creo que el CLR lo permite, ya que otra publicación demuestra con un ejemplo de vb.net y no debe restringirse, pero no me gustaría crear una aplicación basada en las mismas reglas en las que opera el CLR. La abstracción hace el código más claro. Creo que el argumento funciona en el mismo nivel que la herencia múltiple. Sí, se puede hacer en algunos idiomas, pero causa confusión. Por lo tanto, mi respuesta sería reducir la ambigüedad y la confusión y se basa en el compilador/analizador C#. Una elección de diseño del equipo de C#.

Cuestiones relacionadas