¿Debe una propiedad tener el mismo nombre que su tipo?

A veces he visto código escrito así:

public class B1 { } public class B2 { private B1 b1; public B1 B1 { get { return b1; } set { b1 = value; } } } 

es decir, la clase B2 tiene una propiedad llamada “B1”, que también es del tipo “B1”.

Mi instinto me dice que esta no es una buena idea, pero ¿hay alguna razón técnica por la que debas evitar darle a una propiedad el mismo nombre que a su clase?

(Estoy usando .net 2.0, en caso de que eso importe).

Está bien. El ejemplo canónico aquí es

 public Background { public Color Color { get; set; } } 

Hay problemas poco frecuentes (casos de esquina) que aparecen aquí, pero no lo suficiente como para justificar el evitar este dispositivo. Francamente, creo que este dispositivo es bastante útil. No me gustaría no poder hacer lo siguiente:

 class Ticker { ... } public StockQuote { public Ticker Ticker { get; set; } } 

No quiero tener que decir Ticker StockTicker o Ticker ThisTicker etc.

La Guía de Naming de Microsoft para miembros dice:

Considere darle a una propiedad el mismo nombre que su tipo.

Cuando tiene una propiedad fuertemente tipada en una enumeración, el nombre de la propiedad puede ser el mismo que el nombre de la enumeración. Por ejemplo, si tiene una enumeración llamada CacheLevel , una propiedad que devuelve uno de sus valores también se puede CacheLevel .

Aunque admito que hay una pequeña ambigüedad ya sea que solo estén recomendando esto para Enums o para propiedades en general.

Solo puedo pensar en un inconveniente. Si quisieras hacer algo como esto:

 public class B1 { public static void MyFunc(){ ; } } public class B2 { private B1 b1; public B1 B1 { get { return b1; } set { b1 = value; } } public void Foo(){ B1.MyFunc(); } } 

En su lugar, tendría que usar:

 MyNamespace.B1.MyFunc(); 

Un buen ejemplo de esto es el uso común en la progtwigción de Winforms, donde la clase System.Windows.Forms.Cursor se superpone con la propiedad System.Windows.Forms.Form.Cursor, por lo que los eventos de formulario tienen que acceder a los miembros estáticos que utilizan el espacio de nombres completo. .

Justo hoy, Eric blogueó sobre el problema del ‘Color del color’.

http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx

Personalmente, lo evitaría si fuera posible.

No hay un problema técnico específico con eso. Podría dañar o mejorar la legibilidad. De hecho, algunas bibliotecas de Microsoft tienen este tipo de propiedades (específicamente, con propiedades enum , esto normalmente tiene sentido).

Otra gotcha es con tipos internos.

Me encuentro con este todo el tiempo:

 public class Car { public enum Make { Chevy, Ford }; // No good, need to pull Make out of the class or create // a name that isn't exactly what you want public Make Make { get; set; } } 

Obviamente, puede ser un poco confuso cuando el nombre de una propiedad y su tipo son los mismos, pero aparte de eso, no es realmente un problema.

Si el nombre tiene sentido, generalmente es mejor dejar que el nombre y el tipo sean los mismos. Si puede pensar en un nombre mejor, debe usarlo, pero no debe tratar de inventar un nombre a cualquier costo solo para evitar esta situación.

Este patrón común es una de las razones por las que siempre uso this cuando me refiero a un miembro de instancia dentro de una clase. por ejemplo, siempre

 this.SomeMethod(this.SomeProperty); 

y nunca

 SomeMethod(SomeProperty); 

En la mayoría de los casos, no hay ninguna ambigüedad real, pero creo que ayuda a aclarar las cosas. Además, ahora sabe dónde se define la propiedad / método.

Le doy a las cosas el mismo nombre que a su tipo, excepto en el caso: mis métodos y propiedades son “lowerCase”; y por lo tanto, no tendría el problema que tiene MiffTheFox.

 public class B1 { public static void myFunc(){ ; } } public class B2 { private B1 m_b1; public B1 b1 { get { return m_b1; } set { m_b1 = value; } } public void Foo() { B1.myFunc(); //this is Ok, no need to use namespace } } 

Entonces, para mí, m_b1 es información de miembro, b1 es una propiedad (o una variable o parámetro local), y B1 es el nombre de la clase.