Propiedades frente a 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 creo haber captado las propiedades debido a lo que he llegado a comprender sobre la encapsulación y los modificadores de campo (privado, público, etc.).

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 encapsulación. Pensé que lo entendía por la capacidad del uso de los modificadores (privado, público, interno, protegido). Sin embargo, después de conocer las propiedades, estoy algo desgarrado al comprender no solo 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 deberías tratar de usarlas en lugar de campos cuando puedas debido a:

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

2) agregan 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 hizo # 2, me pareció que las propiedades solo generaban código adicional a menos que tuvieras alguna razón para cambiar el tipo (# 1) – porque eres (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 Propiedades, lo que complica aún más mi comprensión de la necesidad de 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 las propiedades frente a los campos frente a la encapsulación (y buenos métodos de progtwigción).

¿Alguien puede explicar:

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

2) ¿ Algún consejo sobre reconocer el uso de propiedades y no verlas como simples métodos (con la excepción de que el conjunto get sea aparente) al rastrear el código de otras personas?

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

Gracias y disculpas por la publicación larga. No quería hacer solo una pregunta 100 veces sin explicar por qué la estoy volviendo a preguntar.

No debe preocuparse por el código adicional necesario para acceder a los campos a través de propiedades, el comstackdor JIT lo “optimizará” (al subrayar el código). Excepto cuando es demasiado grande para ser alineado, pero de todos modos necesitabas el código adicional.

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

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

Cuando necesite personalizar , siempre podrá definir su propio campo más adelante.

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

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

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

Siempre debe usar propiedades donde sea posible. Extraen el acceso directo al campo (que se crea para usted si no crea uno). Incluso si la propiedad no hace nada más que establecer un valor, puede protegerte más adelante. Cambiar un campo a una propiedad más adelante es un cambio radical, por lo que si tiene un campo público y desea cambiarlo a una propiedad pública, debe volver a comstackr todo el código que originalmente accedió a ese campo.

2) ¿Algún consejo sobre reconocer el uso de propiedades y no verlas como simples métodos (con la excepción de que el conjunto get sea aparente) al rastrear el código de otras personas?

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

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

Siempre uso propiedades para obtener y establecer métodos cuando sea posible. De esa forma puedo agregar código más adelante si necesito verificar que el valor esté dentro de ciertos límites, no nulo, etc. Sin usar propiedades, tengo que regresar y poner esas verificaciones en cada lugar al que acceda directamente al campo.

Una de las cosas buenas de Properties es que el getter y el setter pueden tener diferentes niveles de acceso. Considera 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. Lea sobre Dependency Injection. La inyección de constructores y la inyección de propiedades se refieren a las propiedades de configuración desde algún tipo 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 dependency injection también lo ayudará con su tercera pregunta sobre buenas prácticas.

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

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

a) Al tener la siguiente

 public string MyProperty { get; private set; } 

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

b) Si decide que necesita boost la seguridad de sus propiedades de uso del código:

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

2) Puedes decir que son propiedades porque no tienen () . El comstackdor le dirá si intenta agregar corchetes.

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

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

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

Además, si tiene varios proyectos que dependen el uno del otro, tiene que volver a comstackr todo lo que dependa de aquel en el que se cambió un campo a una propiedad.

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 que desee realizar alguna acción cuando una propiedad cambie, puede vincular algunos manejadores a eventos PropertyChanging o PropertyChanged. En el caso de los campos esto no es posible. Los campos pueden ser públicos o privados o protegidos, en el caso de los accesorios, puede hacerlos de solo lectura, pero de forma 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 usar un método cuando se espera que el valor de retorno sea dynamic cada vez que llame, una propiedad debe usarse cuando el valor de retorno no es tan dynamic.

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

Sí, recomiendo leer las pautas de Framework Design para las mejores prácticas de buena progtwigción.

Una advertencia es que cosas como “Threading.Interlocked.Increment” pueden funcionar con campos, pero no pueden funcionar con propiedades. Si dos hilos llaman simultáneamente a Threading.Interlocked.Increment en SomeObject.LongIntegerField, el valor boostá en dos, incluso si no hay otro locking. Por el contrario, si dos hilos invocan simultáneamente Threading.Interlocked.Increment en SomeObject.LongIntegerProperty, el valor de esa propiedad puede boostse en dos, o en uno, o en -4,294,967,295, o quién sabe qué otros valores (la propiedad se puede escribir utilizar valores de locking de prevención distintos de uno o dos en ese escenario, pero no se pudo escribir para garantizar el incremento correcto en dos).

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

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

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

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

Otra buena razón para considerar Propiedades: digamos que usted usa una fábrica para construir algún objeto que tenga un constructor predeterminado, y usted prepara el objeto a través de sus Propiedades.

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

Pero si los usuarios externos vuelven a tener un objeto nuevo, tal vez haya algunas propiedades que desee que vean como de solo lectura y no puedan establecerse (solo la fábrica debería poder configurarlas). Puede hacer que los ajustadores sean internos; esto solo funciona, por supuesto, si la clase del objeto está en el mismo ensamblaje que la fábrica.

Hay otras maneras de lograr este objective, pero es bueno considerar el uso de propiedades y la variada visibilidad de los accesores si está haciendo un desarrollo basado en interfaces, o si expone bibliotecas a otros, etc.

Las propiedades son la forma preferida de cubrir los campos para aplicar la encapsulación. Sin embargo, son funcionales porque puedes exponer una propiedad que es de un tipo diferente y organizar el casting; puedes cambiar los modificadores de acceso; se usan en el enlace de datos WinForms; le permiten incrustar lógica ligera por propiedad, como notificaciones de cambio; etc.

Al mirar el código de otras personas, las propiedades tienen diferentes icons de intellisense para los métodos.

Si cree que las propiedades son solo un código adicional, me gustaría pegarme con ellas de todos modos, pero haga su vida más fácil mediante la generación automática de la propiedad desde el campo (haga clic derecho -> Refactorizar -> Encapsular campo …)

Las propiedades le permiten hacer otras cosas además de establecer u obtener un valor cuando las usa. En particular, te permiten hacer una lógica de validación.

Una mejor práctica es hacer que cualquier cosa que esté expuesta al público sea una propiedad. De esta forma, si cambia la lógica set / get más adelante, solo tiene que volver a comstackr su clase, no todas las clases vinculadas a ella.