Pregunta

Vamos a echar un objeto creado en un captador de esta manera:

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 más bien crear un método que va a crear y devolver el objeto?

¿Fue útil?

Solución

Propiedades parecen campos pero son métodos. Esto ha sido conocido por causar una cantidad fenomenal de confusión. Cuando un programador ve código que parece estar accediendo a un campo, hay muchas suposiciones que hace que el programador que puede no ser cierto para un property.So hay algunas propiedades comunes directrices de diseño.

  1. Evitar la devolución de valores diferentes de la propiedad de captador. Si se llama varias veces en una fila, 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 sobre el objeto original; Consultar un campo siempre devuelve una referencia a un objeto que está garantizado para ser 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 con frecuencia no está documentado.

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

  4. Evitar larga duración captadores de propiedad. Un método propiedad puede tomar mucho tiempo para su ejecución; Acceso campo siempre termina inmediatamente.

  5. Evitar lanzar excepciones de captadores.

  6. Do preservar los valores anteriores si un regulador de la propiedad se produce una excepción

  7. Evitar los efectos secundarios observables.

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

Fuentes

" CLR a través de C # ", Jeffrey Richter. Capítulo 9. Definir las propiedades de forma inteligente

" esquema de diseño Directrices " 2ª edición, Brad Abrams, Krzysztof Cwalina , Capítulo 5.2 Diseño propiedad

Otros consejos

Sí, es una mala práctica.

Lo ideal sería que un captador no debería estar cambiando o creando nada (aparte de carga lenta, y aún así creo que conduce al código tan claro ...). De esta manera se minimiza el riesgo de efectos secundarios no intencionales.

Si usted quiere que su captador para crear un nuevo objeto cada vez que se accede a ella, esa es la manera de hacerlo. Este patrón es normalmente referido como un Método de fábrica .

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

Sí, es ... desde el exterior, debe ser transparente, si accede a una propiedad o un campo ...

cuando se lee dos veces de campo, o una propiedad, se espera dos cosas:

  • no hay impacto en el comportamiento del objeto (externo)
  • se obtienen resultados idénticos

No tengo ningún conocimiento real de C #, pero espero que, a continuación se hace que mi punto claro. Vamos a empezar de esta manera:

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

en el caso de un campo, condiciones como la siguiente será cierto:

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

si utiliza una propiedad con un captador, que devuelve un nuevo objeto cada vez que se llama, ambas condiciones será falsa ...

el captador parece estar destinado a producir una instantánea temporal de su ejemplo ... si eso es lo que quiere hacer, que lo convierten en un método sencillo ... que evita cualquier ambigüedad ...

Una propiedad debe, a todos los efectos, actuar como un campo. Eso significa que no hay excepciones deben ser desechados, y no hay nuevos objetos se deben crear (por lo que no se crea un montón de objetos innecesarios si la propiedad se utiliza en un bucle)

Utilice una clase de contenedor o similar en lugar.

De acuerdo a mi si algo es 'propiedad' del captador se debe devolver una propiedad (básicamente un conjunto de datos que ya existe) pertinentes al objeto.

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

Me gustaría ir con un método algo así como GetMyObject () en su lugar. Especialmente si hay una 'acción' se llevará a cabo, creo que es más de las veces es mejor tener un método que no sea una propiedad Nombre .

Y tratar de imaginar lo que otros desarrolladores que no están familiarizados con su código de esperar que después de ver su propiedad.

Una propiedad es simplemente una manera conveniente de expresar un campo calculado.

Todavía debe representar algo sobre un objeto, independientemente de cómo el valor mismo se llega a. Por ejemplo, si el objeto en cuestión es una factura, es posible que tiene que sumar el costo de cada partida, y devolver el total.

Lo que está escrito en los descansos de interrogación esa regla, porque el retorno de una copia del objeto no es algo que describe el objeto. Si cambia el valor de retorno de una llamada a la propiedad sin un cambio explícito de estado del objeto , entonces el modelo de objetos se ha roto.

Hablando en términos generales, que devuelve un nuevo objeto como esto será casi siempre romper la regla (no puedo pensar en un contraejemplo en este momento), así que diría que es una mala práctica.

También existe la Gotcha de propiedades donde se puede llamar de manera fácil y inocentemente en un múltiplo propiedad veces y terminar de ejecutar el mismo código (que esperemos que no es lento!).

Para escribir código que se prueba fácilmente, usted tiene que mantener la separación de la inicialización de objetos.

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

Al igual que en casa objeto que no desea nada prueba relacionada con objetos de cocina. y wana probar sólo el jardín. así que mientras se inicia una clase de casa e iniciar objeto en algunos constructores o de captadores que no será una buena codificación que apoyarán las pruebas.

En un aparte con los comentarios ya realizados, puede encontrarse con algunos dolores de cabeza de depuración reales cuando los campos de carga diferida a través de una propiedad.

Yo tenía una clase con

private Collection<int> moo;

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

A continuación, en otra parte de la clase había un método público que hace referencia

this.moo.Add(baa);

sin comprobar que se crea una instancia.

Se lanzó una excepción de referencia nula, como se esperaba. Pero la excepción estaba en un hilo de interfaz de usuario, donde lo que no inmediatamente obvio que venía. Empecé rastreo a través de, y cada vez que rastreada a través de, desapareció el error.

Durante un tiempo, tengo que admitir que pensé que me estaba volviendo loca. Depurador - ningún error. Error de tiempo de ejecución. Gran parte de rascarse la cabeza más tarde descubrió el error, y se dio cuenta de que el Visual Studio depurador fue una instancia de la colección, ya que muestra las propiedades públicas de la clase.

Es tal vez como máximo aceptable para structs. Para los tipos de referencia, que no haría sino crear un nuevo objeto en un captador cuando sólo hace una vez usando un patrón perezoso carga.

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

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

Como lo tienes es malo, pero no dis similar a una práctica aceptable llamada carga diferida que se puede leer aquí.

http: // www .aspcode.net / Lazy-carga-de-estructuras-en-C-howto-parte-8.aspx

Es una mala práctica. Pero si usted está pensando en objetos como un grupo de captadores y definidores usted debe comprobar las discusiones clásicas sobre el tema.

Como algunas personas han mencionado, la carga diferida podría ser una razón para hacerlo. Depende de la lógica de negocio real que se está modelando aquí. Usted debe crear un método separado si es mejor para los propósitos de legibilidad, pero si el código para crear el objeto es simple podría evitar el direccionamiento indirecto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top