Propiedades vs. Campos: Necesita ayuda para comprender los usos de las propiedades sobre los campos


En primer lugar, he leído una lista de publicaciones sobre este tema y no siento haber captado las propiedades debido a lo que había llegado a entender sobre la encapsulación y los modificadores de campo (privado, público..Tec).

Uno de los principales aspectos de C# que he aprendido es la importancia de la protección de datos dentro de su código mediante el uso de la encapsulación. I 'pensamiento' entendí que para ser debido a la capacidad del uso de los modificadores (privado, público interno, protegido). Sin embargo, después de aprender sobre las propiedades, no solo entiendo los usos de las propiedades, sino también la importancia/capacidad general de la protección de datos (lo que entendí como encapsulación) dentro de C#.

Para ser más específico, todo lo que he leído cuando llegué a las propiedades en C # es que debe intentar usarlas en lugar de campos cuando pueda debido a:

1) le permiten cambiar el tipo de datos cuando no puede al acceder directamente al campo directamente.

2) añaden un nivel de protección al acceso a los datos

Sin embargo, por lo que 'pensé' que había llegado a saber sobre el uso de modificadores de campo #2, me pareció que las propiedades solo generaban código adicional a menos que tuviera alguna razón para cambiar el tipo (#1) - porque está (más o menos) creando métodos ocultos para acceder a los campos en lugar de directamente.

Luego están los modificadores completos que se pueden agregar a las propiedades que además complica mi comprensión de la necesidad de las propiedades para acceder a los datos.

He leído varios capítulos de diferentes escritores sobre "propiedades" y ninguno ha explicado realmente una buena comprensión de propiedades vs.campos vs. encapsulación (y buenos métodos de programación).

Puede alguien explicar:

1) por qué querría usar propiedades en lugar de campos (especialmente cuando aparece solo estoy agregando código adicional

2) cualquier consejo sobre reconociendo el uso de propiedades y no viéndolas simplemente como métodos (con la excepción de que el get;set sea aparente) al rastrear el código de otros pueblos?

3) ¿Alguna regla general cuando se trata de buenos métodos de programación en relación con cuándo usar qué?

Gracias y lo siento por el post largo - no quería simplemente hacer una pregunta que se ha hecho 100x sin explicar por qué lo estoy haciendo de nuevo.

Author: skaffman, 2010-06-18

12 answers

No debe preocuparse por el código adicional necesario para acceder a los campos a través de propiedades, será "optimizado" por el compilador JIT (insertando el código). Excepto cuando es demasiado grande para ser inlineado, pero entonces necesitabas el código extra de todos modos.

Y el código extra para definir propiedades simples también es mínimo:

public int MyProp { get; set; } // use auto generated field.

Cuando necesites personalizar siempre puedes definir tu propio campo más tarde.

Así que se queda con la capa adicional de encapsulación / datos protección, y eso es algo bueno.

Mi regla: exponer campos siempre a través de propiedades

 8
Author: GvS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 13:30:35

1) por qué querría usar propiedades en lugar de campos (especialmente cuando parece que solo estoy agregando adicional código

Siempre debe usar propiedades cuando sea posible. Resumen el acceso directo al campo (que se crea para usted si no crea uno). Incluso si la propiedad no hace otra cosa que establecer un valor, puede protegerlo más adelante. Cambiar un campo a una propiedad más tarde es un cambio de última hora, por lo que si tiene un campo público y desea cambiar it to a public property, you have to recompile all code which originally accessed that field.

2) cualquier consejo sobre el reconocimiento del uso de propiedades y no verlos como métodos simply (con la excepción de el get; set siendo aparente) cuando seguimiento de otros pueblos código?

No estoy totalmente seguro de lo que está pidiendo, pero al rastrear el código de otra persona, siempre debe asumir que la propiedad está haciendo algo más que simplemente obtener y establecer un valor. A pesar de que es una práctica aceptada no poner grandes cantidades de código en getters y setter, no se puede asumir que, ya que es una propiedad, se comportará rápidamente.

3) Cualquier regla general del pulgar cuando viene a buenos métodos de programación en ¿relación con cuándo usar qué?

Siempre uso propiedades para obtener y establecer métodos cuando es posible. De esa manera puedo agregar código más tarde si necesito verificar que el valor está dentro de ciertos límites, no null, etc. Sin usar propiedades, tengo que volver y poner esos cheques en cada lugar que accedí directamente al campo.

 21
Author: kemiller2002,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 14:02:18

Una de las cosas buenas de las propiedades es que el getter y el setter pueden tener diferentes niveles de acceso. Considere esto:

public class MyClass {

  public string MyString { get; private set; }

  //...other code
}

Esta propiedad solo se puede cambiar desde dentro, por ejemplo en un constructor. Lee sobre la inyección de Dependencia. Tanto la inyección de constructor como la inyección de propiedades se ocupan de establecer propiedades desde alguna forma de configuración externa. Hay muchos marcos por ahí. Si profundiza en algunos de estos obtendrá una buena idea de las propiedades y su uso. La inyección de dependencia también le ayudará con su 3a pregunta sobre buenas prácticas.

Al mirar el código de otras personas, puede saber si algo es un método o una propiedad porque sus iconos son diferentes. Además, en Intellisence, la primera parte del resumen de una propiedad es la propiedad word.

 11
Author: Daniel Dyson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 13:41:01

1) Hay varias razones por las que es posible que desee utilizar Propiedades sobre los campos, aquí hay solo un par:

A) Teniendo lo siguiente

public string MyProperty { get; private set; }

Está haciendo la propiedad "solo lectura". Nadie que use su código puede modificar su valor. Hay casos en los que esto no es estrictamente cierto (si su propiedad es una lista), pero estos son conocidos y tienen soluciones.

B) Si decide que necesita aumentar la seguridad de sus propiedades de uso de código:

public string MyProperty
{
    get { return _myField; }
    set
    {
        if (!string.IsNullOrEmpty(value))
        {
            _myField = value;
        }
    }
}

2) Se puede decir son propiedades porque no tienen (). El compilador le dirá si intenta agregar corchetes.

3) Se considera una buena práctica usar siempre propiedades.

 7
Author: ChrisF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 13:29:23

Aunque no me gusta exponer directamente los campos al público, hay otra cosa: Los campos no se pueden exponer a través de Interfaces; las propiedades sí.

 7
Author: sunside,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 14:10:30

Hay muchos escenarios donde usar un campo simple no causaría daño, pero
una propiedad se puede cambiar más fácilmente más adelante, es decir, si desea agregar un evento cada vez que cambie el valor o si desea realizar alguna comprobación de valor/rango.

Además, si tiene varios proyectos que dependen unos de otros, debe recompilar todos los que dependen de aquel en el que un campo se cambió a una propiedad.

 3
Author: Morfildur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 13:26:38

why I would want to use properties instead of fields (especially when it appears I am just adding additional code

Desea usar propiedades sobre campos porque, cuando usa propiedades, puede usar eventos con ellos, por lo que en un caso en el que desea realizar alguna acción cuando una propiedad cambia, puede vincular algunos controladores a PropertyChanging o PropertyChanged events. En caso de campos esto no es posible. Los campos pueden ser públicos o privados o protegidos, en el caso de props puede hacerlos de solo lectura públicamente pero de escritura privada.

any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?

Se debe utilizar un método cuando se espera que el valor devuelto sea dinámico cada vez que llame, se debe usar una propiedad cuando el valor devuelto no sea tan dinámico.

Any general rules of thumb when it comes to good programming methods in relation to when to use what?

Sí, recomiendo encarecidamente leer Directrices de Diseño del Marco para las mejores prácticas de buena programación.

 2
Author: this. __curious_geek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 13:28:25

El uso de campos generalmente se practica en clases privadas que no está destinado a compartir datos con otras clases, Cuando queremos que nuestros datos sean accesibles por otras clases usamos propiedades que tienen la capacidad de compartir datos con otras clases a través de get y set que son métodos de acceso llamados Auto Properties que tienen acceso a datos en clases privadas, también puede usar ambos con modificadores de acceso en la misma clase permitiendo a la clase usar datos de forma privada como campo de datos y al mismo tiempo vincular campo privado a una propiedad que hace que los datos sean accesibles también a otras clases, vea este simple ejemplo:

private string _name;  
public string Name    
{
   get
     {
       return _name;
     }
   set
     {
      _name = value;
     }
}

La cadena privada _name solo es utilizada por la clase, mientras que la propiedad Name es accesible por otras clases en el mismo espacio de nombres.

 2
Author: Ashraf Abusada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-31 10:05:39

Una advertencia es que cosas como " Enhebrar.Entrelazado.Increment " puede funcionar con campos, pero no con propiedades. Si dos hilos llaman simultáneamente al hilo.Entrelazado.Incremento en SomeObject.LongIntegerField, el valor se incrementará en dos incluso si no hay otro bloqueo. Por el contrario, si dos hilos llaman simultáneamente al hilo.Entrelazado.Incremento en SomeObject.LongIntegerProperty, el valor de esa propiedad puede incrementarse en dos, o en uno, o por -4,294,967,295, o quién sabe qué otros valores (la propiedad podría escribirse para usar bloqueo prevenir valores que no sean uno o dos en ese escenario, pero no podría escribirse para asegurar el incremento correcto en dos).

 1
Author: supercat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 17:11:59

Iba a decir que las Propiedades (setters) son un gran lugar para generar eventos como NotifyPropertyChanged, pero alguien más se me adelantó.

Otra buena razón para considerar las propiedades: digamos que usas una fábrica para construir un objeto que tiene un constructor predeterminado, y preparas el objeto a través de sus propiedades.

new foo(){Prop1 = "bar", Prop2 = 33, ...};

Pero si los usuarios externos actualizan su objeto, tal vez haya algunas propiedades que desea que vean como de solo lectura y no puedan establecer (solo la fábrica debe ser capaz de establecer)? Puede hacer que los setters sean internos - esto solo funciona, por supuesto, si la clase del objeto está en el mismo ensamblaje que la fábrica.

Hay otras formas de lograr este objetivo, pero el uso de Propiedades y la visibilidad variable de los accesores es una buena opción a considerar si está haciendo un desarrollo basado en interfaces, o si expone bibliotecas a otros, etc.

 1
Author: pelazem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-23 14:38:26

Las propiedades

Son la forma preferida de cubrir campos para imponer la encapsulación. Sin embargo, son funcionales, ya que puede exponer una propiedad que es de un tipo diferente y ordenar el casting; puede cambiar los modificadores de acceso; se utilizan en el enlace de datos de WinForms; le permiten incrustar lógica ligera por propiedad, como notificaciones de cambio; etc.

Cuando se mira el código de otros pueblos, las propiedades tienen iconos intellisense diferentes a los métodos.

Si usted piensa las propiedades son solo código extra, yo diría que se queda con ellos de todos modos, pero hacer su vida más fácil mediante la auto-generación de la propiedad desde el campo (clic derecho- > Refactor - > Encapsular Campo...)

 0
Author: Adam Houldsworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 13:24:04

Las propiedades le permiten hacer cosas que no sean establecer u obtener un valor cuando las usa. En particular, le permiten hacer lógica de validación.

Una Buena Práctica es hacer de todo lo expuesto al público una Propiedad. De esta manera, si cambias la lógica set/get en un momento posterior, solo tienes que recompilar tu clase, no todas las clases enlazadas contra ella.

 0
Author: Powerlord,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 13:28:50