¿Debo preferir propiedades con o sin campos privados?

14

El código base en el que estoy trabajando ahora tiene la convención de usar campos privados y propiedades públicas. Por ejemplo, la mayoría de las clases tienen sus miembros definidos de esta manera:

// Fields
private double _foo;
private double _bar;
private double _baz;

// Properties
public double Foo
{
    get{ return _foo; }
    set{ _foo = value; }
}

public double Bar
{
    get{ return _bar; }
    set{ _bar = value; }
}

public double Baz
{
    get{ return _baz; }
}

Sé que estos pueden reescribirse sin sus propiedades privadas internas:

public double Foo{ get; set; }
public double Bar{ get; set; }
public double Baz{ get; private set; }

Me gustaría algún comentario sobre esto:

  • ¿Existe una buena razón para preferir el estilo más antiguo y explícito sobre el más nuevo, más conciso?
  • ¿Debo escribir cualquier clase nueva usando el estilo conciso, o debo intentar hacer coincidir el código anterior para ¿consistencia? ¿Vale la pena la coherencia en este caso para justificar el formato anterior?
pregunta KChaloux 16.08.2012 - 20:37

4 respuestas

14

Hay un par de instancias en las que aún se requiere el llamado estilo "antiguo":

A: tipos inmutables que utilizan la inmutabilidad proporcionada por el lenguaje. El modificador readonly en C # congela ese valor después de la construcción. No hay forma de imitar esto con propiedades implementadas automáticamente (todavía).

public sealed class FooBarBazInator
{
    private readonly double foo;

    public FooBarBazInator(double foo)
    {
        this.foo = foo;
    }

    public double Foo
    {
        get
        {
            return this.foo;
        }
    }
}

B: Tus getters / set tienen cualquier tipo de lógica. El código WPF y Silverlight (y similares) que están vinculados a los datos de tus clases implementarán INotifyPropertyChanged así:

public class FooBarBazInator : INotifyPropertyChanged
{
    private double foo;

    public event PropertyChangedEventHandler PropertyChanged;

    public double Foo
    {
        get
        {
            return this.foo;
        }

        set
        {
            this.foo = value;
            this.RaisePropertyChanged("Foo");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var propertyChanged = this.PropertyChanged;

        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Aparte de esos, yo diría que usa el nuevo estilo. Mantiene su código conciso y ofrece menos área de superficie para que se introduzcan errores. Además, si alguna vez necesita cambiar para incluir la lógica, no será incompatible con la firma.

    
respondido por el Jesse C. Slicer 16.08.2012 - 20:54
6

Yo diría que tener un campo de respaldo explícito es simplemente inútil: hace que su código sea más largo y más difícil de leer. También agrega potencial de error:

public double Bar
{
    get { return _baz; }
    set { _bar = value; }
}

Creo que un error como este podría ocurrir con bastante facilidad y sería muy difícil de detectar.

Y si desea coherencia, hágalo de la otra manera: cambie el código que usa los campos de respaldo en el código que usa propiedades automáticas. Esto es especialmente fácil si usas una herramienta de refactorización como ReSharper (y si no usas algo así, creo que deberías comenzar).

Por supuesto, todavía hay casos en los que es necesario tener un campo de respaldo, pero creo que eso no es relevante para esta pregunta.

    
respondido por el svick 16.08.2012 - 20:54
1

Aunque la pregunta es bastante antigua, pensé en agregar un par de puntos que leí en un libro que vale la pena mencionar aquí.

  1. Los motores de serialización en tiempo de ejecución conservan el nombre del archivo archivado en una secuencia serializada. El nombre del campo de respaldo para una propiedad implementada automáticamente (AIP) está determinado por el compilador, y en realidad podría cambiar el nombre de este campo de respaldo cada vez que vuelva a compilar su código, negando la posibilidad de deserializar instancias de cualquier tipo que contenga un AIP. Por lo tanto, no utilice AIP con ningún tipo que intente serializar o deserializar.

  2. Al depurar, no puede poner un punto de interrupción en un método de obtención o configuración de AIP, por lo que no puede detectar fácilmente cuándo una aplicación está recibiendo o configurando esta propiedad. Puede establecer puntos de interrupción en puntos de interrupción implementados manualmente

respondido por el Ram 13.05.2015 - 14:13
-3
  

¿Existe una buena razón para preferir el estilo más antiguo y explícito al estilo más reciente y conciso?

En realidad no. Aunque diría que cada vez que pasaste por una propiedad como esa, para empezar, deberías haber usado un campo público.

  

¿Debo escribir cualquier clase nueva usando un estilo conciso, o debo intentar hacer coincidir el código más antiguo para mantener la coherencia? ¿Vale la pena la coherencia en este caso para justificar el formato anterior?

Suponiendo que usted ignoró los consejos anteriores y tiene propiedades de acceso, no intentaría igualar el estilo. Lo ideal sería volver atrás y refactorizar el estilo antiguo al estilo nuevo para que sea consistente, pero la posibilidad de que las personas lean mal ese código es escasa.

    
respondido por el Telastyn 16.08.2012 - 20:54

Lea otras preguntas en las etiquetas