Pregunta

Veo un montón de código de ejemplo para las clases de C# que hace esto:

public class Point {
    public int x { get; set; }
    public int y { get; set; }
}

O, en el código anterior, el mismo con una explícita privado copia de valor y sin el nuevo servicio de auto-aplicado propiedades:

public class Point {
    private int _x;
    private int _y;

    public int x {
        get { return _x; }
        set { _x = value; }
    }

    public int y {
        get { return _y; }
        set { _y = value; }
    }
}

Mi pregunta es ¿por qué.¿Hay alguna diferencia funcional entre la anterior y haciendo estos miembros campos públicos, como el de abajo?

public class Point {
    public int x;
    public int y;
}

Para ser claro, entiendo el valor de getters y setters cuando usted necesita hacer alguna traducción de los datos subyacentes.Pero en los casos en los que acaban de pasar los valores a través de, parece innecesariamente detallado.

¿Fue útil?

Solución

Tiendo a estar de acuerdo (que parece innecesariamente prolijo), aunque este ha sido un tema de nuestro equipo no se ha resuelto todavía y para que nuestros estándares de codificación todavía insisten en detallado de las propiedades de todas clases.

Jeff Atwood lidiado con esto hace un par de años.El punto más importante que retrospectivamente cuenta de que a cambio de un campo de una propiedad es un cambio de hora en el código;nada de lo que consume debe ser recompilado para trabajar con la nueva interfaz de clase, así que si cualquier cosa fuera de su control está consumiendo su clase podría tener problemas.

Otros consejos

También es mucho más sencillo para cambiar esto más adelante:

public int x { get; private set; }

Encapsula la configuración y el acceso de los miembros.Si algún tiempo a partir de ahora un desarrollador para que el código necesita un cambio de lógica cuando un miembro se accede o conjunto se puede hacer sin cambiar el contrato de la clase.

La idea es que, incluso si la estructura de datos subyacente que necesita cambiar, la interfaz pública de la clase no tiene que ser cambiado.

C# puede tratar de variables y propiedades de manera diferente a veces.Por ejemplo, usted no se puede pasar de propiedades como la ref o fuera de los parámetros.Así que si usted necesita para cambiar la estructura de datos por alguna razón y que estaba utilizando variables públicas y ahora lo que necesita para utilizar las propiedades, su interfaz se tienen que cambiar y ahora el código que accede a la propiedad x no puede más tiempo de compilación como lo hizo cuando fue la variable x:

Point pt = new Point();
if(Int32.TryParse(userInput, out pt.x))
{
     Console.WriteLine("x = {0}", pt.x);
     Console.WriteLine("x must be a public variable! Otherwise, this won't compile.");
}

El uso de propiedades desde el inicio evita esto, y usted puede sentirse libre para ajustar la implementación subyacente tanto como usted necesita sin romper el código de cliente.

Setter y Getter permite añadir una capa de abstracción y en la programación orientada a objetos puro siempre se debe obtener acceso a los objetos a través de la interfaz que se proporciona con el mundo exterior ...

Considere la posibilidad de este código, que le ahorrará en asp.net y que no sería posible sin el nivel de abstracción proporcionada por los setters y getters:

class SomeControl
{

private string _SomeProperty  ;
public string SomeProperty 
{
  if ( _SomeProperty == null ) 
   return (string)Session [ "SomeProperty" ] ;
 else 
   return _SomeProperty ; 
}
}

Desde auto implementado captadores lleva el mismo nombre de la propiedad real y el almacenamiento privado de las variables.¿Cómo se puede cambiar en el futuro?Creo que el punto que se ha dicho es que uso el auto implementa en lugar de campo, de modo que usted puede cambiar en el futuro si en el caso de que usted necesita para añadir lógica getter y setter.

Por ejemplo:

public string x { get; set; }

y, por ejemplo, ya el uso de la x un montón de veces y no quiero romper su código.

¿Cómo se puede cambiar el auto getter setter...por ejemplo, para el setter que sólo permite el establecimiento de un número de teléfono válido formato...¿cómo se puede cambiar el código para que sólo la clase se debe cambiar?

Mi idea es agregar una nueva variable privada y agregar el mismo x getter y setter.

private string _x;

public string x { 
    get {return x}; 
    set {
        if (Datetime.TryParse(value)) {
            _x = value;
        }
    }; 
}

Es esto lo que quieres decir por lo que es flexible?

También a tener en cuenta es el efecto del cambio en público cuando se trata de la unión y la serialización.Ambos de estos a menudo se basan en las propiedades públicas para recuperar y establecer los valores.

También, usted puede poner puntos de interrupción en getters y setters, pero no en los campos.

AFAIK el generado CIL interfaz es diferente.Si usted cambia de un miembro público de la propiedad que usted está cambiando su interfaz pública y la necesidad de reconstruir todos los archivos que utiliza esa clase.Esto no es necesario si sólo cambia la aplicación de los getters y setters.

Tal vez simplemente haciendo que los campos de público que podría conduce a una más Anémico Modelo De Dominio.

Saludos

También vale la pena señalar que no se puede hacer Automático Propiedades de sólo lectura y no puede seleccionarlos en línea.Ambas son cosas que me gustaría ver en un futuro de liberación de .NET, pero creo que se puede hacer ni en .NET 4.0.

Las únicas veces que yo uso un campo de respaldo con las propiedades de estos días es cuando mi clase implementa INotifyPropertyChanged y tengo que despedir a la OnPropertyChanged evento cuando una propiedad cambia.

También en estas situaciones me puse los campos de copia de seguridad directamente cuando se pasan los valores de un constructor (no hay necesidad de tratar y fuego la OnPropertyChangedEvent (que sería NULO en este momento de todos modos), en cualquier otro lugar puedo usar la propiedad en sí.

Nunca se sabe si se puede prescindir de la traducción de los datos más tarde.Usted está preparado para que si se esconden de sus miembros.Los usuarios de la clase no aviso si se agrega la traducción ya que la interfaz sigue siendo la misma.

La mayor difrence es que, si alguna vez cambio de su estructura interna, usted todavía puede mantener los getters y setters como es, el cambio de su lógica interna, sin hacer daño a los usuarios de su API.

Si tiene que cambiar la forma de conseguir que x y y en este caso, usted puede agregar las propiedades más tarde.Esto es lo que me parece más confuso.Si uso público variables miembro, usted puede fácilmente cambiar una propiedad más tarde, y el uso privado de variables denominadas _x e _y si usted necesita para almacenar el valor internamente.

Los Setters y getters son malos en principio (son una mala OO olor--voy a dejar de decir que son un anti-patrón, porque lo que realmente son necesarios a veces).

No, No es técnicamente no hay diferencia y cuando realmente quiero compartir el acceso a un objeto en estos días, en ocasiones me hacen público final en lugar de añadir un getter.

La forma en que los setters y getters fueron "Vendidos" es que usted puede ser que necesite saber que alguien está recibiendo un valor o cambiar uno-que sólo tiene sentido con primitivas.

Bolsa de propiedades de los objetos como DAOs, Dto y los objetos de visualización se excluyen de esta regla, ya que estos no son los objetos en un verdadero "OO Diseño" significado de la palabra Objeto.(De no pensar en "envío de Mensajes" a un DAO, Es simplemente un montón de parejas atributo-valor).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top