2009-08-14 11 views
50

En gran parte del código que he visto (en SO, thecodeproject.com y tiendo a hacer esto en mi propio código), he visto propiedades públicas que se crean para cada campo privado que una clase contiene, incluso si son el tipo más básico de get; set; como:¿Debo usar propiedades públicas y campos privados o campos públicos para los datos?

private int myInt; 
public int MyInt 
{ 
    get { return myInt; } 
    set { myInt = value } 
} 

Mi pregunta es: ¿Cómo difiere esto de:

public int MyInt; 

y si debemos utilizar propiedades en lugar de campos públicos ¿por qué debemos usar en este específica ¿caso? (No estoy hablando de ejemplos más complejos en los que los getters y los setters realmente hacen algo especial o solo hay un get o set (solo lectura/escritura) en lugar de solo devolver/establecer un valor de un campo privado). ¡No parece agregar ninguna encapsulación adicional, solo da un bonito icono en IntelliSense y se coloca en una sección especial en los diagramas de clase!

+0

¿No es esto realmente un duplicado? –

+0

¡Es difícil de creer que esta pregunta no se haya formulado aquí hasta ahora! –

+0

Lo fue, y lo hice, creo. Espera mientras lo busco ... – RCIX

Respuesta

30

Ver este artículo http://blog.codinghorror.com/properties-vs-public-variables/

Específicamente

  • Reflexión funciona de forma diferente en las variables vs. propiedades, por lo que si se basan en la reflexión, es más fácil de usar todas las propiedades.
  • No se puede databind contra una variable.
  • Cambiar una variable a una propiedad es un cambio radical.
+1

El uso de propiedades es preferible al uso de campos porque puede cambiar las instrucciones en los bloques get y set sin tener que cambiar las clases que dependen de la propiedad. – user2211290

0

Hay muchas razones por las cuales.

Principalmente:

  • Usted puede hacer algunas otras funciones cuando la variable se establece
  • Usted puede prevenir el establecimiento y proporcionar sólo recibe
  • Algunos sólo el trabajo 'cosas' en las propiedades (DataBinding, por ejemplo,)
  • Puede ocultar la implementación de la propiedad [quizás sea una variable ViewState, en ASP.NET).
5

Bueno, eso hace la diferencia. Los datos públicos se pueden cambiar sin que la instancia del objeto lo sepa. Usando getters y setters el objeto siempre sabe que se ha realizado un cambio.

Recuerde que encapsular los datos es solo el primer paso hacia un diseño mejor estructurado, no es un objetivo final en sí mismo.

0

El punto es - ¿y si al final de la línea que desea asegurarse de que cada vez se hace referencia a myInt ocurre algo especial (un archivo de registro se escribe, que ha cambiado a 42, etc)? No puedes hacer eso sin getters y setters. A veces es conveniente programar para lo que pueda necesitar, no lo que necesita en este momento.

+0

Para algunos tipos, tales escenarios son realistas. Para otros, no lo son. ¿Puedes pensar en algo que una versión futura de 'Point' pueda hacer útilmente en un getter o setter de propiedades? Si 'Point' fuera una clase con propiedades * virtuales *, las futuras clases derivadas podrían agregar comportamientos útiles, pero dado que las instancias' Point 'particulares no tienen idea de para qué se usan, y se espera que acepten ' Los valores de Int32' para 'X' y' Y', no puedo pensar en nada que una implementación futura pueda agregar. – supercat

19

tres razones:

  1. no se pueden sustituir los campos en las subclases que puede hacerlo propiedades.
  2. Puede que necesite un getter o setter más complejo, pero si se trata de un campo, cambiarlo rompería la API.
  3. Convención. Así es como está hecho.

Estoy seguro de que hay más razones por las que no estoy pensando.

En .Net 3.x puede utilizar las propiedades automáticas de esta manera:

public int Age { get; set; } 

en lugar de la vieja escuela con declarar sus campos privados a sí mismo de esta manera:

private int age; 

public int Age 
{ 
    get { return age; } 
    set { age = value; } 
} 

Esto hace que sea tan simple como crear un campo, pero sin el problema del cambio de ruptura (entre otras cosas).

+0

= 1: ¿dónde consigues que los campos no se puedan serializar? –

+1

"Eventualmente puede necesitar un getter o setter más complejo, pero si se trata de un campo, cambiarlo rompería la API". No realmente. Puede ir de forma segura desde: public int Joe; a privado int _joe; public int Joe { get {// hacer algo} conjunto {// hacer algo}} Puede que tenga que cambiar un montón de referencias internas, pero eso no quiere romper su API. –

+0

@ John Saunders eso es lo que he leído ... ¿no es verdad? fue alguna vez verdad? –

0

En realidad, si está utilizando Silverlight, se dará cuenta de que los campos no se pueden establecer como recursos estáticos y, por lo tanto, tendrá que usar una propiedad (incluso para acceder a const).

Me he dado cuenta de que cuando traté de federar los nombres de región que uso en la Guía compuesta (PRISM).

Sin embargo, eso es solo un límite de idioma y aparte de los campos static/const siempre siempre uso propiedades.

0

La idea es que no debe cambiar accidentalmente/involuntariamente el valor de un campo privado de clase fuera. Cuando usa get y set, eso significa que está cambiando el campo privado de la clase intencionalmente y con conocimiento.

6

Cuando se crea ámbito privado nombre y una simple propiedad pública Nombre que realmente obtiene y establece la nombre del valor campo

public string Name 
{ 
    get { return name; } 
} 

y utiliza esta propiedad en todas partes fuera de su clase y un día usted decide que la propiedad Nombre de esta clase se referirá realmente al campo lastName (o que desea devolver una cadena "Mi nombre:" + nombre), simplemente cambie el código dentro la propiedad:

public string Name 
{ 
    get { return lastName; //return "My name: "+name; } 
} 

Si estaba utilizando ámbito público nombre todas partes en el código fuera, entonces tendría que cambiar el nombre a lastName todas partes que lo utilizó.

0

El establecimiento de un valor en un campo privado sólo cambia ese campo, pero por lo que en la propiedad que puede manejar otros argumentos, por ejemplo, puede llamar a un método después de establecer un valor

 
private string _email; 
public string Email 
{ 
    get 
    { 
     return this._email; 
    } 
    set 
    { 
     this._email = value; 
     ReplaceList(); //** 
    } 
} 




+0

Ok, pero no necesita hacer nada más que simplemente devolver el _correo electrónico. Y entonces, ¿cuál es el motivo de usar la propiedad? Y la razón está en m-respuesta - para el uso futuro. – agnieszka

2

Es ... depende ?

siempre uso captadores & organismos, desde que crearon este atajo:

public int Foo {get; conjunto; }

En tiempo de compilación que se traduce.Ahora no puedes hacerte elegante con eso, pero está ahí, y si necesitas ser elegante, solo lo deletreas más tarde.

Sin embargo, público, privado, protegido ... todo es cuestión de quién quiere que sea capaz de modificar los datos. Usamos mucho la herencia y este es un método muy común para nosotros, por lo que solo los niños pueden editar ciertas propiedades.

protected _foo; 
public Foo 
{ 
    get { return _foo; } 
} //lack of set intentional. 
-1

No puedo creer que con 11 respuestas, nadie ha dicho esto:

No todos los campos privados debe ser expuesto como propiedades públicas. Sin duda, debe utilizar propiedades para todo lo que no sea privado, pero debe mantener la privacidad de la mayor parte de su clase.

+1

Vuelve a leer la pregunta: Necesito que estos campos privados sean accesibles desde fuera de la clase en este caso. ¡Por supuesto que no harías que cada campo sea público o le des una propiedad a cada campo! –

+0

En realidad, la pregunta no dice nada sobre lo que necesita, solo acerca de lo que ha visto crear propiedades públicas para cada campo privado. Si tiene campos que requieren acceso público, entonces no son campos privados, y no coinciden con lo que estaba haciendo la pregunta. Edite la pregunta para aclarar qué tiene _código_, a diferencia de los ejemplos que ha visto "en SO, thecodeproject.com" –

4

usted tiene que utilizar las propiedades en los siguientes casos:

  1. Cuando se necesita para serializar los datos en la propiedad de algún formato.
  2. Cuando necesita anular propiedades en la clase derivada.
  3. Cuando implementa métodos get y set con cierta lógica. Por ejemplo, cuando implementa un patrón de Singleton.
  4. Cuando se deriva de la interfaz, donde se declaró la propiedad.
  5. Cuando tiene problemas específicos relacionados con Reflection.
+2

¿Por qué cree que los campos no se pueden serializar? –

Cuestiones relacionadas