2009-01-30 12 views
7

Cuando enlace datos de mi xaml a algunos datos, a menudo uso la parte "obtener" de una propiedad para hacer algo de lógica. Como dar a la suma de los totales de una lista o un cheque si algo es positivo.Lógica en obtener parte de la propiedad. ¿Buena práctica?

Por ejemplo:

public List<SomeClass> ListOfSomeClass{get;set;} 

public double SumOfSomeClass 
{ 
    get 
    { 
    return ListOfSomeClass.Sum(s => s.Totals); 
    } 
} 

public bool SumPositive 
{ 
    get 
    { 
    if(SumOfSomeClass >= 0) 
     return true; 
    else 
     return false; 
    } 
} 

De esta manera puedo obligar a SumPositive y SumOfSomeClass. ¿Esto se considera una buena práctica? Incluso si se vuelve más complejo que esto? ¿O sería mejor llamar a un método y devolver el resultado? ¿Qué pasa con las llamadas a otra clase o incluso una base de datos?

Respuesta

14

Se espera que los captadores de propiedades sean rápidos e idempotentes (es decir, no se deben realizar acciones destructivas allí). Aunque es perfectamente correcto iterar sobre una colección de objetos en la memoria, no recomendaría hacer ningún tipo de trabajo pesado en obtener o piezas. Y hablando de iterar, todavía almacena el resultado en caché para ahorrar unos pocos milisegundos.

+1

"ahorrar unos milisegundos" ¿nanosegundos? –

+1

idempotent tiene un significado más amplio que eso: significa que obtiene el mismo resultado llamando a la operación repetidamente, en lugar de verse afectado por un estado memorizado. http://en.wikipedia.org/wiki/Idempotent –

1

Dije que sí, pero intente almacenar en una variable privada de los resultados de ListOfSomeClass.Sum (s => s.Totals). Especialmente si lo usa más de una vez.

1

Tener lógica compleja en getters/setters no es una buena práctica. Recomiendo mover la lógica compleja a métodos separados (como GetSumOfXYZ()) y usar memoization en accesos a propiedades.

Puede evitar las propiedades complejas usando ObjectDataProvider - le permite definir el método para extraer algunos datos.

1

No veo ningún problema directo (a menos que la lista sea bastante grande) pero personalmente usaría el método myInstance.SomeList.Sum() si es posible (.net> = 2.0).

1

Para los cálculos básicos fuera de los campos u otras propiedades en la colección, sería aceptable hacerlo dentro de la propiedad Obtener. Como todos los demás dijeron que la verdadera lógica nunca debería hacerse en el getter.

0

Depende ... si esto fuera una entidad de dominio, entonces no estaría a favor de tener lógica compleja en un getter y especialmente no en un setter. El uso de un método (para mí) le indica al consumidor de la entidad que se está realizando una operación mientras que un captador indica una recuperación simple.

Ahora, si esta lógica estaba en un ViewModel, entonces creo que el aspecto getter es un poco más perdonable/esperado.

0

Creo que hay un cierto nivel de lógica que se espera en Getters and Setters, de lo contrario solo tienes una especie de forma enrevesada para declarar a tus miembros como públicos.

2

Sí, a menos que sea una operación que pueda tener implicaciones de rendimiento. En ese caso se debe utilizar un método en su lugar (ya que es más intuitivo para el usuario final que un método podría ser lento mientras que una propiedad será rápido)

1

cambia por favor que getter a esto:

public bool SumPositive 
{ 
    get 
    { 
    return SumOfSomeClass >= 0; 
    } 
} 

Ya está usando una expresión booleana, no es necesario devolver explícitamente verdadero o falso

+0

Eso es lo que realmente uso en mi código. En el ejemplo, se supone que debe "verse" más complejo;) – Sorskoot

1

Me gustan sus convenciones de nomenclatura y estoy totalmente de acuerdo con el uso de contenido como su ejemplo en captadores de propiedades, si está entregando una API para ser utilizado con encuadernación

No estoy de acuerdo con el punto que otros han hecho acerca de mover el código a un método solo porque es computacionalmente pesado - esa no es una distinción que alguna vez haría ni he escuchado que otras personas sugieran que estar implicado en un método implica más lento que una propiedad.

Creo que las propiedades deberían estar libres de efectos secundarios en el objeto al que se las llama. Es mucho más difícil garantizar que no tengan ningún efecto en un entorno más amplio: incluso una propiedad relativamente trivial puede extraer datos en la memoria o al menos cambiar el caché del procesador o el estado de vm.

0

Tendría cuidado al poner cualquier lógica en el Getter de una propiedad. Cuanto más caro es hacer, más peligroso es. Otros desarrolladores esperan que un getter devuelva un valor inmediatamente al igual que obtener un valor de una variable miembro. He visto muchas instancias en las que un desarrollador usa una propiedad en cada iteración de un ciclo, pensando que solo están recuperando un valor, mientras que la propiedad en realidad está haciendo un montón de trabajo. Esto puede ser una gran desaceleración en la ejecución del código.

Cuestiones relacionadas