2009-09-15 11 views
12

¿Existe alguna manera de continuar utilizando las propiedades implementadas automáticamente mientras se sigue produciendo un evento de cambio, como INotifyPropertyChanged, cuando se llama a Set?Propiedades implementadas automáticamente en C#

En lugar de:

private string _value; 
public string Value 
{ 
    get 
    { 
    return this._value; 
    } 
    set 
    { 
    this._value = value; 
    this.ValueChanged(this,EventArgs.Empty); 
    } 
} 

¿Puedo hacer:

public string Value 
{ 
    get; 
    set 
    { 
    this.ValueChanged(this,EventArgs.Empty); 
    } 
} 

Aunque la incubadora se ve mal, ¿es posible hacer esto sin llenar mi clase con variables respaldo de la tienda?

ACTUALIZACIÓN: parece que no hay una solución estándar para mi objetivo perezoso, creo que la mejor solución es usar CodeRush o Resharper para generar todas mis tiendas de respaldo para mí.

Respuesta

6

No se puede hacer esto. La especificación para las características implementadas de forma automática es bastante claro:

implementan automáticamente propiedades (auto-aplicado) automatizan este patrón. Más específicamente, declaraciones de bienes no abstractos se permite tener punto y coma de acceso cuerpos. Ambos métodos de acceso deben estar presentes y ambos deben tener punto y coma cuerpos, pero pueden tener diferentes modificadores de accesibilidad. Cuando una propiedad se especifica así, un campo de respaldo será automáticamente generado para la propiedad, y los accesos se implementarán para leer y escribir en ese campo de respaldo. El nombre del campo de respaldo es compilador generado e inaccesible al usuario .

En otras palabras, sólo pueden tener "get;" y "", con la posibilidad de modificadores de acceso.

4

No, no puede, porque usted no tiene acceso al ámbito privado que ha generado para esa propiedad

4

Una rápida búsqueda en Google sobre "propiedades de auto INotifyPropertyChanged" le llevará a varios blogs y artículos sobre el tema. Aquí hay uno:

INotifyPropertyChanged auto wiring or how to get rid of redundant code

+0

Aunque puedo ver que esto va a funcionar, en realidad se parece más desordenado que el uso de variables respaldo tiendas – benPearce

+0

benPearce: Una propiedad automática es para cuando no quiere escriba cualquier otro código en setter o getter. Si lo hace (como notificar cambios de propiedad), entonces necesita escribirlo. No estoy de acuerdo con el enfoque de PostSharp, pero ciertamente es una solución de algún tipo. Estoy bastante cómodo con el código que escribe manualmente las variables. –

+0

sedoso: estoy de acuerdo contigo en el Postsharp, si bien es una solución, no estoy especialmente interesado en ella. – benPearce

1

Esto se le ha preguntado al equipo de Microsoft detrás de C# 3.0 y dijeron que lo pensarían, tienen una lectura de here.

En los comentarios que encontrará más información, incluyendo por qué es una mala idea si se necesita más control, así como los medios para lograrlo.

1

Usted puede utilizar algún marco AOP como PostSharp.

Pero puede reducir el rendimiento y el tiempo de construcción.

+0

Parece que Postsharp 2.0 hace exactamente esto - http://www.postsharp.org/blog/introducing-postsharp-20-1-notifypropertychanged – benPearce

0

Este comportamiento se puede hacer con un generador de proxy de tipo fábrica. Ya lo hice en mi Framework de desarrollo. Si usa System.Reflection.Emit, puede crear un tipo proxier.Considere ejemplo abajo:

var a = Proxier<InputType>.CreateInstance(new object[] { }); // object arrays are for different constructors 
a.PropertyAccessed += ... 
0

El Fody complemento PropertyChanged hace esto. Al igual que KindOfMagic, Fody usa Mono.Cecil para modificar el IL de ensamblajes .net en tiempo de compilación. El siguiente ejemplo aparece en la documentación PropertyChanged:

escribe:

[ImplementPropertyChanged] 
public class Person 
{   
    public string GivenNames { get; set; } 
    public string FamilyName { get; set; } 

    public string FullName 
    { 
     get 
     { 
      return string.Format("{0} {1}", GivenNames, FamilyName); 
     } 
    } 
} 

Lo que se compiló:

public class Person : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    string givenNames; 
    public string GivenNames 
    { 
     get { return givenNames; } 
     set 
     { 
      if (value != givenNames) 
      { 
       givenNames = value; 
       OnPropertyChanged("GivenNames"); 
       OnPropertyChanged("FullName"); 
      } 
     } 
    } 

    string familyName; 
    public string FamilyName 
    { 
     get { return familyName; } 
     set 
     { 
      if (value != familyName) 
      { 
       familyName = value; 
       OnPropertyChanged("FamilyName"); 
       OnPropertyChanged("FullName"); 
      } 
     } 
    } 

    public string FullName 
    { 
     get 
     { 
      return string.Format("{0} {1}", GivenNames, FamilyName); 
     } 
    } 

    public virtual void OnPropertyChanged(string propertyName) 
    { 
     var propertyChanged = PropertyChanged; 
     if (propertyChanged != null) 
     { 
      propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

la wiki incluye algunos ejemplos más avanzados.

Está disponible usando NuGet:

PM> Install-Package PropertyChanged.Fody 
Cuestiones relacionadas