property practices ejemplos coding codigo best attribute c# coding-style properties field

c# - practices - ¿Por qué utilizar campos en lugar de propiedades?



property c# get set (13)

Como otros han notado, necesitarás un campo de respaldo privado para las propiedades de todos modos.

También hay una ventaja de velocidad en el uso de campos sobre las propiedades. En el 99.99% de los casos no importará. Pero en algunos podría.

Soy bastante nuevo en C #, y creo que las propiedades son maravillosas. Tan maravilloso, de hecho, que no puedo ver ninguna ventaja real en el uso de campos, en cambio. Incluso para los campos privados, parece que la flexibilidad y la modularidad que ofrecen las propiedades pueden, en el mejor de los casos, ahorrarle dolores de cabeza graves y, en el peor de los casos, no tener ningún efecto.

La única ventaja que puedo ver para los campos es que puedes inicializarlos en línea. Pero la mayoría de las veces, desea inicializarlos en el constructor, de todos modos. Si no está utilizando la inicialización en línea, ¿hay alguna razón para no usar propiedades todo el tiempo?

Editar: Algunas personas han mencionado la necesidad de hacer una copia de seguridad de las propiedades con campos (explícita o automáticamente). Permite aclarar mi pregunta: ¿Hay alguna razón para usar los campos, excepto para hacer una copia de seguridad de las propiedades ? Es decir, ¿hay algún momento en que SomeType someField; es preferible a SomeType SomeProperty { get; set; } SomeType SomeProperty { get; set; } SomeType SomeProperty { get; set; } ?

Editar 2: DanM, Skurmedel y Seth dieron respuestas realmente útiles. Acepté el de DanM, ya que es el más completo, pero si alguien resumiera sus respuestas en una sola respuesta, estaría encantado de aceptarlo.


Hay varias respuestas buenas (parciales) de @Seth (los campos tienen un mejor rendimiento, por lo que en un contexto privado, puede usar eso para su beneficio cuando tiene sentido), @Skurmedel (los campos pueden ser de solo lectura), @Jenk (los campos pueden ser utilizado para ref / out). Pero me gustaría agregar uno más:

Puede usar la sintaxis de inicialización simplificada para establecer el valor de un campo, pero no una propiedad. es decir:

private int x = 7;

vs

private int x { get; set; } // This must go in the constructor, sometimes forcing you to create // a constructor that has no other purpose. x = 7;


Intente usar una propiedad cuando use ref / out args:

someObject.SomeMethod(ref otherObject.SomeProperty);

No compilará


La sintaxis de los campos es mucho más rápida de escribir que de las propiedades, por lo que cuando es seguro usar un campo (privado para la clase) ¿por qué no usarlo y guardar ese tipeo adicional? Si las propiedades implementadas automáticamente tuvieran la breve sintaxis concisa corta y tuvieras que hacer un trabajo extra para crear un campo viejo simple, las personas podrían comenzar a usar propiedades en su lugar. Además, es una convención ahora en C #. Así es como piensan las personas, y es lo que esperan ver en el código. Si haces algo diferente de lo normal, confundirás a todos.

Pero podría preguntar por qué la sintaxis de los campos no crea una propiedad implementada automáticamente en lugar de un campo, por lo que obtiene lo mejor de ambos mundos: propiedades en todas partes y una sintaxis concisa.

Hay una razón muy simple por la que aún necesitamos tener campos explícitos:

C # 1.0 no tenía todas estas características agradables que tenemos ahora, por lo que los campos eran un hecho de la vida, no se podía vivir sin ellos. Montones y montones de código dependen de que los campos y las propiedades sean cosas visiblemente diferentes. Simplemente no se puede cambiar ahora sin romper toneladas de código.

Sospecho también que hay implicaciones de rendimiento, pero quizás eso se pueda resolver con el jitter.

Así que estamos atrapados en los campos para siempre, y como están ahí y han tomado la mejor sintaxis, tiene sentido usarlos cuando sea seguro hacerlo.


Las propiedades son maravillosas, pero hay gastos generales asociados con el acceso a la propiedad. No necesariamente es un problema, sino algo a tener en cuenta.

Evitar el uso excesivo de captadores de propiedades y setters

La mayoría de las personas no se dan cuenta de que los buscadores de propiedades y los incubadores son similares a los métodos cuando se trata de sobrecarga; es principalmente la sintaxis que los diferencia. El compilador incluirá un getter o setter de propiedad no virtual que no contenga instrucciones distintas al acceso de campo, pero en muchos otros casos esto no es posible. Debes considerar cuidadosamente tu uso de las propiedades; desde dentro de una clase, acceda directamente a los campos (si es posible) y nunca llame ciegamente a las propiedades repetidamente sin almacenar el valor en una variable. Dicho todo esto, ¡esto no significa que debas usar campos públicos!

Fuente: http://dotnet.sys-con.com/node/46342


Los campos son el único lugar donde puede almacenar estado. Las propiedades son en realidad solo un par de métodos con sintaxis especial que les permite mapearse al método get o set, dependiendo de cómo se estén usando: si una propiedad modifica o accede al estado, ese estado todavía tiene que ser almacenado en un campo .

No siempre ves los campos. Con las propiedades automáticas C # 3, el compilador crea el campo para usted. Pero todavía está allí. Además, las propiedades automáticas tienen algunas limitaciones importantes (por ejemplo, sin soporte INotifyPropertyChanged, sin lógica comercial en los setters) que significan que a menudo son inapropiadas, y usted necesita crear un campo explícito y una propiedad definida manualmente de todos modos.

Según la respuesta de David , tiene razón si habla de una API: casi nunca desea que el estado interno (campos) forme parte de la API.


Los campos y las propiedades no son intercambiables. Supongo que lo que estás diciendo es acceder a campos privados a través de propiedades privadas. Hago esto cuando tiene sentido, pero en su mayor parte, no es necesario. El optimizador JIT tendrá acceso en línea a un campo privado a través de una propiedad privada en la mayoría de los casos de todos modos. Y envolver un campo privado en una propiedad privada no se considera un cambio radical ya que los miembros privados no son parte de su interfaz.

Personalmente, nunca expondría ningún campo de instancia protegida / pública. Sin embargo, generalmente es aceptable exponer un campo público estático con un modificador de solo lectura, siempre que el tipo de campo sea inmutable. Esto se ve a menudo con los campos estáticos SomeStruct.Empty.


No hay ninguna razón para exponer públicamente los campos.

Si expone públicamente un campo, no puede cambiar el origen de la información, desde la definición en línea hasta el archivo de configuración sin refactorizar.

Podría usar un campo para ocultar datos internos. Raramente estoy a favor de eso, solo uso campos cuando estoy haciendo algo para ocultarlo públicamente y usarlo en una propiedad. (es decir, no estoy usando la generación automática de propiedades)


No veo por qué usarías autopropiedades privadas. ¿Qué ventaja hay para

private int Count {get; set;}

encima

private int count


Normalmente, las propiedades necesitan un campo de respaldo a menos que sean simples "propiedades automáticas" getter / setter.

Entonces, si solo estás haciendo ...

public string Name { get; set; } // automatic property

... no necesitas un campo, y estoy de acuerdo, no hay razón para tener uno.

Sin embargo, si lo estás haciendo ...

public string Name { get { return _name; } set { if (value = _name) return; _name = value; OnPropertyChange("Name"); } }

... necesita ese campo de respaldo _name .

Para las variables privadas que no requieren ninguna lógica especial get / set, realmente es una decisión de juicio si se debe hacer una propiedad automática privada o solo un campo. Normalmente hago un campo, luego, si necesito que esté protected o sea public , lo cambiaré a una propiedad automática.

Actualizar

Como señaló Yassir, si usas propiedades automáticas, todavía hay un campo al acecho detrás de escena, simplemente no es algo que realmente tengas que escribir. Entonces, la conclusión es que las propiedades no almacenan datos, sino que proporcionan acceso a los datos. Los campos son los que realmente contienen los datos. Entonces, los necesitas aunque no puedas verlos.

Actualización 2

En cuanto a su pregunta revisada ...

¿Hay algún momento en que SomeType someField; es preferible a SomeType SomeProperty { get; set; } SomeType SomeProperty { get; set; } SomeType SomeProperty { get; set; } ?

... una cosa que viene a la mente: si tiene un campo privado, y (de acuerdo con la convención para campos privados) lo llama _name , que le indica a usted y a cualquier persona que lea su código que está trabajando directamente con datos privados. Si, por otro lado, haces que todo sea una propiedad, y (de acuerdo con la convención de propiedades) llames a tu propiedad privada Name , ahora no puedes simplemente mirar la variable y decir que se trata de datos privados. Entonces, usar solo propiedades quita algo de información. No he intentado trabajar con todas las propiedades para evaluar si esa es información crucial, pero definitivamente algo se pierde.

Otra cosa, más pequeña, es esa public string Name { get; set; } public string Name { get; set; } public string Name { get; set; } requiere más tipeo (y es un poco más desordenado) que private string _name .


Si bien estoy de acuerdo con lo que percibo como el "intento" en la declaración de David Basarab: "No hay motivo para exponer públicamente los campos", me gustaría añadir un énfasis ligeramente diferente:

Modificaría la cita de David arriba para que diga: "No hay ninguna razón para exponer públicamente campos ... fuera de una clase ... excepto a través de la opción consciente de encapsular los campos en Propiedades a través de los cuales se controla rigurosamente el acceso.

Las propiedades no son simplemente un "barniz" de sintaxis sobre los campos "añadidos" a C #: son una característica fundamental del lenguaje diseñada por buenas razones, que incluyen:

  1. controlando lo que está expuesto y no expuesto fuera de las clases (encapsulación, ocultación de datos)

  2. Permitir que se realicen ciertas acciones cuando se accede o establece una propiedad: acciones que se expresan mejor en el conjunto de propiedades ''get'' y ''get'', en lugar de ser ''elevadas'' a métodos definidos externamente.

  3. Las interfaces por diseño no pueden definir ''campos: pero pueden definir Propiedades.

Good OO Design significa tomar decisiones conscientes sobre el "estado":

  1. campos de variables locales: qué estado es privado para un método y transitorio : las variables locales normalmente solo son válidas dentro del alcance de un cuerpo de método, o incluso con una "vida útil reducida" dentro del alcance de algo así como un bucle for. Por supuesto, también puede considerar las variables de parámetro en un método como "local".

  2. campos de instancia de clase: qué estado es privado para una clase y tiene existencia independiente para cada instancia de una clase, pero lo más probable es que se requiera su uso en varios lugares de la clase.

  3. campos de instancia estáticos: qué estado será una propiedad de la clase solamente, independientemente del número de instancias de la clase.

  4. estado expuesto deliberada y conscientemente "fuera" de la clase: la idea clave es que hay al menos un nivel de indirección interpuesto entre la clase y los "consumidores" de los datos que la clase expone. El "lado opuesto" de "exposición" es, por supuesto, la intención consciente de ocultar (encapsular, aislar) el código de implementación.

    a. a través de propiedades públicas: todos los aspectos de esto están bien cubiertos en todas las otras respuestas aquí

    segundo. a través de indexadores

    do. a través de métodos

    re. las variables estáticas públicas se encuentran generalmente en clases de utilidad, que a menudo son clases estáticas.

Sugerir opinión: MSDN on ''Fields ... MSDN on Properties ... MSDN on Indexers


Si quieres tener algo readonly , tienes que usar un campo, ya que no hay forma de decirle a una propiedad automática que genere un campo de solo lectura.

Lo hago con bastante frecuencia.

Ejemplo de ejemplo:

class Rectangle { private readonly int _width; private readonly int _height; public Rectangle(int width, int height) { _width = width; _height = height; } public int Width { get { return _width; } } public int Height { get { return _height; } } }

Esto significa que nada dentro de Rectangle puede alterar el ancho o la altura después de la construcción. Si uno intenta, el compilador se quejará.

Si en cambio hubiera usado una propiedad automática con un setter privado, el compilador no me protegería de mí mismo.

Otra razón que veo es que si una información no tiene que estar expuesta (permanecer en private ) ¿por qué convertirla en una propiedad?


Velocidad. Si un campo se establece o lee miles de millones de veces en el transcurso de una simulación, entonces desea utilizar un campo y no una propiedad para evitar la sobrecarga de una llamada secundaria. Conforme a OO (DDD?) Tanto como sea posible, en estos casos, recomendaría recurrir a los campos solo en la clase dedicada a representar a algún tipo de persona de "valor". La lógica debe mantenerse al mínimo. Más bien, tenga un creador personal o un asesor personal.

Pero si tienes estos problemas, entonces probablemente no estés programando c ++ y no c #, ¿no?