2009-12-02 21 views
10

mi pregunta es simple, ¿está utilizando las propiedades get set de C# consideradas buenas, incluso mejor que escribir métodos getter y setter? Cuando utiliza estas propiedades, ¿no tiene que declarar a los miembros de sus datos de clase como públicos? Pregunto esto porque mi profesor declaró que los miembros de los datos deberían nunca declararse como públicos, ya que se considera una mala práctica.¿Está utilizando las propiedades get set de C# como una buena práctica?

Este ....

class GetSetExample 
{ 
    public int someInt { get; set; } 
} 

vs Este ...

class NonGetSetExample 
{ 
    private int someInt; 
} 

Editar:

Gracias a todos ustedes! Todas sus respuestas me ayudaron y voté correctamente sus respuestas.

+0

esto es realmente algo que pedimos cuando entrevistamos nuevas aplicaciones. ¿Por qué usarías el primero sobre el segundo :-) –

+0

¡Los profesores deberían ser lo suficientemente inteligentes como para saber que no se deben usar absolutos! A menos que sea redefinido "nunca" para significar "no sin una comprensión y aceptación de las posibles consecuencias" ... –

Respuesta

14

Este:

class GetSetExample 
{ 
    public int someInt { get; set; } 
} 

es realmente lo mismo que esto:

class GetSetExample 
{ 
    private int _someInt; 
    public int someInt { 
     get { return _someInt; } 
     set { _someInt = value; } 
    } 
} 

La sintaxis get; set; es sólo un atajo conveniente para este que se puede utilizar cuando el getter y setter no hacen algo especial.

Por lo tanto, no está exponiendo a un miembro público, está definiendo un miembro privado y proporcionando métodos get/set para acceder a él.

4

En su primer ejemplo, C# genera automáticamente los campos de respaldo privados, por lo que técnicamente el miembro de datos no se declara como público solo el getter/setter.

+0

Técnicamente, pero es una distinción bastante sin sentido. –

+8

No realmente. Las propiedades se pueden usar en otras áreas mientras que los métodos o campos no. Autoencuadernación viene a la mente. –

+7

En realidad, es bastante importante en algunas situaciones. Si declaras una variable pública, entonces estás atascado con que es una variable pública a menos que quieras cambiar la ABI a ese conjunto.Con un {get; conjunto; } propiedad pública, todos los accesos públicos están sucediendo a través de métodos de acceso para que pueda cambiar los métodos de acceso para tener funcionalidades diferentes más adelante sin obligar a todos a recompilar sus aplicaciones que hacen referencia a su ensamblado. –

0

Es bastante razonable, y su profesor (sin contexto) está equivocado. Pero de todos modos, usar "propiedades automáticas" está bien, y puedes hacerlo ya sea que sean públicas o privadas.

Aunque en mi experiencia, cada vez que uso uno, casi inevitablemente necesito escribir algo de lógica allí, y por lo tanto no puedo usar los accesorios automáticos.

+1

Supongo que el contexto sería Java (o posiblemente C++), ya que Java no tiene propiedades como C#. – FrustratedWithFormsDesigner

+0

Si tiene control completo sobre la fuente completa y siempre está compilada, entonces realmente importa poco si usa propiedades o variables públicas (excepto en situaciones especiales). Sin embargo, en situaciones en las que diferentes personas escriben diferentes partes del código, se vuelve más importante. Las bibliotecas profesionales no exponen variables públicas a código externo. –

+0

Leyendo estas respuestas Me siento un poco como si estuviera en la zona de penumbra. –

7

Sí, los miembros normalmente nunca deben declararse públicos en buen diseño por varias razones. Piensa en OOP donde heredas la clase más tarde. Algo difícil de anular en un campo. :-) También le impide mantener sus internos a los que se accede directamente.

The simplistic get; conjunto; el diseño se introdujo en C# 2.0. Básicamente es lo mismo que declarar todo con un miembro privado que lo respalda (descompílelo en una herramienta como Reflector y vea).

public int someInt{get;set;} 

es directamente iguales a los

private int m_someInt; 
public int someInt{ 
    get { return m_someInt; } 
    set { m_someInt = value; } 
} 

La gran parte de tener el simplificada captador/definidor es que cuando se desea llenar en la ejecución con un poco más agallas posterior, no se rompen Compatibilidad ABI

No se preocupe si getter/setters ralentiza su código indirectamente. El JIT tiene una cosa llamada inlineing que hace que usar el getter/setter sea tan eficiente como el acceso directo al campo.

+1

Estoy de acuerdo. Considerando una larga biblioteca Live .NET. Para mantenerlo, debe tener mucho cuidado antes de exponer algo al mundo exterior, y la mayoría de las veces debe exponer una propiedad, en lugar de un campo. Esta es la forma más segura ya que en futuras versiones, puede cambiar la implementación de esta propiedad sin dañar los ensamblajes de llamada. ¿Qué pasará si expone un campo directamente? Esa debe ser una pesadilla interminable, ya que nunca podrás cambiarla a partir de ese momento. –

1

En un enfoque orientado a objetos "puro", no se considera correcto exponer el estado de los objetos, y esto se aplica a las propiedades tal como se implementan en .NET y get_set_properteis de Java/EJB. La idea es que al exponer el estado de su objeto, está creando dependencias externas a la representación de datos internos de su objeto. Un diseño de objeto puro reduce todas las interacciones a mensajes con parámetros.

De vuelta al mundo real: si tratas de implementar un enfoque teórico tan estricto en el trabajo, o te reirán de la oficina o te harán pedazos. Las propiedades son inmensamente populares porque son un compromiso razonable entre un diseño de objeto puro y datos privados completamente expuestos.

7

Sí. Los miembros de los datos deben ser privados y las propiedades automáticas lo permiten y otorgan acceso público en el camino correcto.

Pero debe tener cuidado. Comprenda que el contexto es muy importante. En la aplicación con subprocesos, actualizar una propiedad después de otra propiedad relacionada puede ser perjudicial para la coherencia. En ese caso, un método setter que actualice los dos miembros de datos privados de forma adecuada tiene más sentido.

0

su profesor tenía toda la razón.

Considere este ejemplo trivial de por qué "captadores" deben evitarse: Puede haber 1.000 llamadas a un método getX() en su programa, y ​​cada una de esas llamadas supone que el valor de retorno es un tipo particular. El valor de retorno de getX() se puede ordenar en una variable local, por ejemplo, y el tipo de variable debe coincidir con el tipo de valor de retorno. Si necesita cambiar la forma en que se implementa el objeto de tal manera que cambie el tipo de X, tendrá un problema grave. Si X solía ser un int, pero ahora tiene que ser un long, ahora obtendrá 1,000 errores de compilación. Si soluciona el problema incorrectamente al convertir el valor devuelto a int, el código se compilará limpiamente pero no funcionará. (El valor de retorno puede verse truncado.) Debe modificar el código que rodea cada una de esas 1,000 llamadas para compensar el cambio. Yo, al menos, no quiero hacer tanto trabajo.

Holub On Patterns

+0

Eso realmente no tiene ningún sentido en el contexto de la pregunta. ¿Cuál es la alternativa? ¿Nunca dejas que alguien recupere a un miembro de la clase? – Sterno

+0

Sterno: bueno, incluso su profesor parece decirlo ("mi profesor afirmó que los miembros de datos nunca deberían declararse como públicos"). ¿Por qué es malo declarar miembros de datos públicos, pero escribir más código para * exactamente el mismo efecto * está bien? –

+0

Estoy de acuerdo con lo que dijo su profesor. Simplemente no creo que lo que citaste tenga mucho sentido en la aplicación práctica. Las herramientas como Resharper hacen que cambiar un tipo de variable sea bastante trivial, e incluso si no estás usando un getter/setter. método, no significa que va a evitar el dolor asociado con el cambio de un tipo de propiedad. Así que, mientras respaldo lo que dijo su profesor, no creo que esta cita haga mucho para apoyar la discusión. – Sterno

1

porque con el miembro de datos públicos, que el miembro de datos se puede cambiar o puede ser leído fuera de clase y no se puede controlar de lectura/escritura accesibilidad operación, pero con propiedades que se pueden controlar de lectura/escritura corriente, por ejemplo, tener en cuenta esta declaración:

public MyVar{private get; public set;} 

significa valor de MyVar sólo puede cambiarse dentro de la clase y se puede leer fuera de clase (léase privada y leer públicamente) y esto no es p posible con sólo miembros de datos públicos

+0

Una nueva sugerencia para el usuario: No es muy útil agregar una respuesta a una pregunta muy antigua, cuando esa pregunta ya tiene un montón de respuestas. – hyde

Cuestiones relacionadas