2012-06-19 8 views
9

¿Vale la pena escribir esta pieza de código:¿Es malo devolver ICommand nuevo cada vez en getter de propiedad?

RelayCommand _saveCommand; 
public ICommand SaveCommand 
{ 
    get 
    { 
     if (_saveCommand == null) 
     { 
      _saveCommand = new RelayCommand(this.Save); 
     } 
     return _saveCommand; 
    } 
} 

en lugar de devolver nuevo objeto cada vez que:

public ICommand SaveCommand 
{ 
    get { return new RelayCommand(this.Save); } 
} 

Por lo que sé captadores de comando se utilizan muy raramente y RelayCommand 's constructor es bastante rápido ¿Es mejor escribir un código más largo?

+2

Qué es lo que tienen que ver con? Código de longitud, uso de memoria, ...? Si es de longitud, puede acortar su primer ejemplo a una línea: 'return _saveCommand ?? (_saveCommand = new RelayCommand (this.Save)); ' – Brunner

+0

¿Por qué no haces' readlyly RelayCommand _saveCommand = new RelayCommand (Save); public ICommand SaveCommand {get {return _saveCommand; }} '? –

+0

O también puede agregar '_saveCommand = new RelayCommand (Save);' en el ctor de su clase –

Respuesta

10

me gusta la null coalescing operator

public ICommand SaveCommand 
{ 
    get { return _saveCommand ?? (_saveCommand = new RelayCommand(this.Save); } 
} 

Devuelve el operando de la izquierda si el operando no es nulo, de lo contrario, devuelve el operando de la derecha.

+0

Aunque me gusta '??' también, siento que no es una respuesta a la pregunta que se hizo. Lo que creo se reduce a "devolver un nuevo objeto cada vez o reutilizar el anterior". – Brunner

+0

@Brunner: Sí, estoy de acuerdo. Pero la pregunta también contenía "¿Es mejor escribir código largo" y '??' lo hace mucho más corto. De todos modos, estaba a punto de editar la pregunta para incluir más información, pero luego las otras respuestas ya estaban publicadas. –

6

Este diseño puede ser engañoso para los usuarios de su clase. Por ejemplo, pueden leer el valor de la propiedad en un bucle con miles de iteraciones. Eso creará muchos objetos nuevos y el usuario probablemente no lo espere.

Consulte la documentación de la advertencia de StyleCop CA1819: Properties should not return arrays - este es un problema muy similar.

Por lo general, los usuarios no comprenderán las consecuencias negativas en el rendimiento de llamar a dicha propiedad. Específicamente, pueden usar la propiedad como una propiedad indexada.

Además, SaveCommand == SaveCommand será falso. Creo que esto es contradictorio.

En resumen, este podría no ser el mejor diseño, sin embargo, si los usuarios de tu código saben cómo funciona y cómo usarlo correctamente, está bien.

1

Sí, es malo devolver un objeto nuevo todo el tiempo. ¿Por que hacerlo? Si, por algún motivo, se llama a ese getter muchas veces, creará nuevos objetos en la memoria todo el tiempo. Si haces eso solo por esta instancia aislada, eso no es tan terrible. Pero si tiene el hábito de programar de esta manera, creará problemas difíciles de encontrar y tendrá una base de códigos que es difícil de mantener. Es mejor ser simple, limpio y elegante en todo momento, y terminar con una base de código agradable, limpia y fácil de mantener.

Por cierto, siempre se puede simplemente inicializar el campo cuando se declara que:

RelayCommand _saveCommand = new RelayCommand(this.Save); 

A continuación, el comprador sólo tiene esto en él:

return _saveCommand; 
Cuestiones relacionadas