visual studio setters getters example and c# oop getter

studio - set c#



¿Es la creación de objetos una mala práctica para los captadores? (14)

Tengamos un objeto creado en un captador como este:

public class Class1 { public string Id { get; set; } public string Oz { get; set; } public string Poznamka { get; set; } public Object object { get { // maybe some more code return new Object { Id = Id, poznamla = Poznamka, Oz = OZ }; } } }

¿O debería crear un método que cree y devuelva el objeto?


Además de los comentarios que ya se han hecho, puede encontrar algunos dolores de cabeza de depuración reales cuando se cargan campos a través de una propiedad.

Tuve una clase con

private Collection<int> moo; public Collection<int> Moo { get { if (this.moo == null) this.moo = new Collection<int>(); return this.moo; } }

Luego, en algún otro lugar de la clase había un método público que hacía referencia

this.moo.Add(baa);

Sin comprobarlo fue instanciado.

Se lanzó una excepción de referencia nula, como se esperaba. Pero la excepción estaba en un subproceso de la interfaz de usuario, por lo que no es obvio de dónde venía. Comencé a rastrear, y cada vez que rastreé, el error desapareció.

Por un tiempo tengo que admitir que pensé que me estaba volviendo loca. Depurador - no hay error. Error de tiempo de ejecución. Después de mucho rascarse la cabeza, detecté el error y me di cuenta de que el depurador de Visual Studio estaba creando una instancia de la Colección al mostrar las propiedades públicas de la clase.



Depende del uso del getter. Es un gran lugar para incluir este tipo de código para la carga perezosa.


Es quizás a lo más aceptable para las struct . Para los tipos de referencia, solo crearía un nuevo objeto en un captador cuando solo se realice una vez utilizando un patrón de carga lenta.


Es una mala práctica. En su ejemplo, debería poder esperar el mismo Object cada vez que acceda a la propiedad del object .


Es una mala práctica. Pero si piensa en los objetos como un grupo de captadores y definidores, debería consultar las discusiones clásicas sobre el tema.

Como mencionaron algunas personas, la carga perezosa podría ser una razón para hacerlo. Depende de la lógica de negocios real que esté modelando aquí. Debería crear un método separado si es mejor por motivos de legibilidad, pero si el código para crear el objeto es simple, podría evitar la indirección.


Las propiedades parecen campos pero son métodos. Se sabe que esto causa una cantidad fenomenal de confusión. Cuando un programador ve un código que parece estar accediendo a un campo, hay muchas suposiciones que el programador hace que pueden no ser ciertas para una propiedad. Por lo tanto, existen algunas pautas comunes de diseño de propiedades.

  1. Evite devolver valores diferentes de la propiedad getter. Si se llama varias veces seguidas, un método de propiedad puede devolver un valor diferente cada vez; un campo devuelve el mismo valor cada vez.

  2. Un método de propiedad puede requerir memoria adicional o devolver una referencia a algo que no es realmente parte del estado del objeto, por lo que la modificación del objeto devuelto no tiene efecto en el objeto original; la consulta de un campo siempre devuelve una referencia a un objeto que se garantiza que forma parte del estado del objeto original. Trabajar con una propiedad que devuelve una copia puede ser muy confuso para los desarrolladores, y esta característica a menudo no está documentada.

  3. Tenga en cuenta que una propiedad no se puede pasar como un parámetro out o ref a un método; un campo puede

  4. Evite los captadores de propiedades de larga ejecución Un método de propiedad puede tardar mucho tiempo en ejecutarse; El acceso al campo siempre se completa de inmediato.

  5. Evita lanzar excepciones de getters.

  6. Conservar los valores anteriores si un establecedor de propiedades lanza una excepción

  7. Evite los efectos secundarios observables.

  8. Permitir que las propiedades se establezcan en cualquier orden, incluso si esto resulta en un estado temporal no válido de objetos.

Fuentes

" CLR via C # ", Jeffrey Richter. Capítulo 9. Definiendo propiedades inteligentemente

" Framework Design Guidelines ", 2ª edición, Brad Abrams, Krzysztof Cwalina, Capítulo 5.2 Diseño de propiedades


Para escribir código que se pueda probar fácilmente, debe mantener la separación de la inicialización del objeto.

es decir, mientras que en los casos de prueba no tiene en espera algunos elementos específicos.

como en el objeto Casa no desea probar nada relacionado con el objeto de la cocina. y tú solo probarás el jardín. así que mientras inicias una clase de casa e inicias un objeto en algunos constructores o en captadores, no estarás codificando bien para soportar las pruebas.


Sí, es una mala práctica.

Idealmente, un captador no debería estar cambiando o creando nada (aparte de la carga perezosa, e incluso entonces creo que conduce a un código menos claro ...). De esa manera usted minimiza el riesgo de efectos secundarios involuntarios.


Según yo, si algo es ''propiedad'', el captador debería devolverle una propiedad (básicamente, datos que ya existen) relevantes para el objeto.

En su caso, está devolviendo algo que no es propiedad de ese objeto en ese momento. No está devolviendo una propiedad de su objeto, sino un producto de alguna acción.

Me gustaría ir con un método algo como GetMyObject () en su lugar. Especialmente si hay una ''acción'' tendrá lugar, creo que la mayoría de las veces es mejor tener un método que un nombre de propiedad.

E intente imaginar lo que otros desarrolladores que no están familiarizados con su código esperan después de ver su propiedad.


Si desea que su captador cree un nuevo objeto cada vez que se accede a él, esa es la manera de hacerlo. Este patrón normalmente se conoce como un método de fábrica .

Sin embargo, esto normalmente no es necesario en las propiedades (es decir, captadores y definidores), y como tal se considera una mala práctica.


Una propiedad debe, a todos los efectos, actuar como un campo. Eso significa que no se deben lanzar excepciones y no se deben crear nuevos objetos (por lo que no se crean muchos objetos innecesarios si la propiedad se usa en un bucle)

Utilice una clase de contenedor o similar en su lugar.


Una propiedad es solo una forma conveniente de expresar un campo calculado.

Todavía debe representar algo acerca de un objeto, independientemente de cómo se llegue al valor en sí. Por ejemplo, si el objeto en cuestión es una factura, es posible que deba sumar el costo de cada artículo de línea y devolver el total.

Lo que está escrito en la pregunta rompe esa regla, porque devolver una copia del objeto no es algo que describa al objeto. Si el valor de retorno cambia entre las llamadas a la propiedad sin un cambio explícito del estado del objeto , el modelo del objeto se rompe.

Hablando en generalidades, devolver un nuevo objeto como este casi siempre romperá la regla (no puedo pensar en un contra-ejemplo en este momento), así que diría que es una mala práctica.

También hay una serie de propiedades en las que puedes llamar a una propiedad de forma tan fácil e inocente varias veces y terminar ejecutando el mismo código (¡lo que esperamos no sea lento!).


sí, es ... desde el exterior, debe ser transparente, ya sea que acceda a una propiedad o un campo ...

Al leer dos veces desde el campo o una propiedad, se esperan dos cosas:

  • No hay impacto en el comportamiento del objeto (externo).
  • obtienes resultados idénticos

No tengo un conocimiento real de C #, pero espero que lo siguiente quede claro. vamos a empezar así:

Object o1 = myInst.object; Object o2 = myInst.object; o1.poznamka = "some note";

en el caso de un campo, condiciones como las siguientes serán verdaderas:

o1 == o2; o2.poznamka == "some note";

Si usa una propiedad con un captador, que devuelve un nuevo objeto cada vez que se llama, ambas condiciones serán falsas ...

su captador parece estar destinado a producir una instantánea temporal de su instancia ... si eso es lo que quiere hacer, en lugar de hacerlo un método sencillo ... evita ambigüedades ...