2010-04-26 10 views
7

Formulario Build your own MVVM he el siguiente código que nos permite tener typesafe llamadas NotifyOfPropertyChange:typesafe NotifyPropertyChanged usando expresiones LINQ

public void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property) 
{ 
    var lambda = (LambdaExpression)property; 
    MemberExpression memberExpression; 
    if (lambda.Body is UnaryExpression) 
    { 
     var unaryExpression = (UnaryExpression)lambda.Body; 
     memberExpression = (MemberExpression)unaryExpression.Operand; 
    } 
    else memberExpression = (MemberExpression)lambda.Body; 
    NotifyOfPropertyChange(memberExpression.Member.Name); 
} 

¿Cómo se compara este enfoque a cadenas simples estándar acercarse performancewise? A veces tengo propiedades que cambian a una frecuencia muy alta. ¿Estoy seguro de usar este tipo de enfoque seguro? Después de algunas primeras pruebas parece hacer una pequeña diferencia. ¿Cuánta CPU puede inducir potencialmente una carga de memoria?

+0

Puede que le interese esta discusión: [** Mejores prácticas: ¿Cómo implementar INotifyPropertyChanged right? **] (http://compositeextensions.codeplex.com/Thread /View.aspx?ThreadId=53731) – jbe

Respuesta

5

¿Cómo se ve el código que provoca este aspecto? Estoy adivinando es algo así como:

NotifyOfPropertyChange(() => SomeVal); 

que es implícita:

NotifyOfPropertyChange(() => this.SomeVal); 

el que hace una captura de this, y bastante-mucho que significa que el árbol de expresión debe ser construido (con Expression.Constant) desde cero cada vez. Y luego lo analiza cada vez. Entonces la sobrecarga definitivamente no es trivial.

¿Es demasiado though? Esa es una pregunta que solo usted puede responder, con perfiles y conocimiento de su aplicación. Se considera que está bien para una gran cantidad de uso de MVC, pero eso no es (generalmente) llamarlo en un ciclo cerrado de larga duración. Necesitas perfil contra un objetivo de rendimiento deseado, básicamente.

+0

Su suposición sobre el aspecto de la llamada es correcta. – bitbonk

+0

comparaciones de perf http://www.pochet.net/blog/2010/06/25/inotifypropertychanged-implementations-an-overview/ – Simon

+0

@Simon por supuesto, en C# 5 los nuevos atributos de nombre de llamada lo convierten en casi una pregunta redundante –

0

utilizo el siguiente método en una clase base implementar INotifyPropertyChanged y es tan fácil y conveniente:

public void NotifyPropertyChanged() 
    { 
     StackTrace stackTrace = new StackTrace(); 

     MethodBase method = stackTrace.GetFrame(1).GetMethod(); 

     if (!(method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))) 
     { 
      throw new InvalidOperationException("The NotifyPropertyChanged() method can only be used from inside a property"); 
     } 

     string propertyName = method.Name.Substring(4); 

     RaisePropertyChanged(propertyName); 
    } 

espero que les sea útil también. :-)

+1

Por favor, no envíe la misma respuesta en varias preguntas. Si la pregunta es un duplicado, deje un comentario que lo indique (o marque si tiene suficiente reputación). Si no es un duplicado, por favor adapte su respuesta a la pregunta formulada. –

1

Cómo sobre el uso del estándar de facto

if (propName == value) return; 
propName = value; 
OnPropertyChanged("PropName"); 

y luego crear una herramienta personalizada que comprueba y refactors el archivo de código de acuerdo con esta norma. Esta herramienta podría ser una tarea previa a la construcción, también en el servidor de compilación. Simple, confiable, realiza.

0

Tipo seguro y sin pérdida de rendimiento: extensión NotifyPropertyWeaver. Agrega en toda la notificación automáticamente antes de compilar ...

Cuestiones relacionadas