Domanda

Ho una classe con un gruppo di proprietà che assomigliano a questo:

public string Name
{
    get { return _name; }
    set { IsDirty = true; _name = value; }
}

Sarebbe molto più facile se avessi potuto contare su C# 3.0 per generare l'archivio di backup per questi, ma c'è un modo per fattore il IsDirty=true;in modo che io possa scrivere la mia proprietà di qualcosa di simile a questo e ancora ottenere lo stesso comportamento:

[MakesDirty]
public string Name { get; set; }
È stato utile?

Soluzione

No.Non senza scrivere molto di più (arcano?) codice rispetto alla versione originale (Devi utilizzare la reflection per controllare l'attributo sulla proprietà e cosa no..mi ha fatto ricordare di essere "più lento")..Questo è il tipo di duplicazione posso vivere.

MS ha la stessa necessità per eventi per la raccolta di quando una proprietà viene modificata.INotifyPropertyChanged che è un'interfaccia essenziale per le notifiche di modifica.Ogni implementazione ho ancora visto non

set
{ 
  _name = value; 
  NotifyPropertyChanged("Name"); 
}

Se fosse possibile, mi piacerebbe capire quei ragazzi intelligenti a MS sarebbe già qualcosa di simile a posto..

Altri suggerimenti

Si potrebbe provare a impostare un frammento di codice per rendere più facile per creare quelle.

Se si vuole veramente andare in quel modo, per modificare quello che fa il codice utilizzando un attributo, ci sono alcuni modi per farlo e sono tutte relative al AOP (Aspect oriented programming).Check out PostSharp, che è un aftercompiler che è possibile modificare il codice in un dopo la fase di compilazione.Per esempio, si potrebbe impostare un attributo personalizzato per le tue proprietà (o l'aspetto, come viene chiamato in AOP) che inietta il codice all'interno della proprietà setter, che segna i tuoi oggetti sporchi.Se volete alcuni esempi di come questo è raggiunto, è possibile controllare la loro tutorial.

Ma attenzione con AOP e perché si può facilmente creare più problemi che stiamo cercando di risolvere, se non utilizzato a destra.

Ci sono più AOP quadri là fuori alcuni post di compilazione e alcuni utilizzando il metodo di meccanismi di intercettazione, che sono presenti in .Net, i successivi hanno un po ' di prestazioni svantaggi rispetto al primo.

No, quando si utilizza la proprietà automatico non hanno alcun controllo sulla loro attuazione.L'opzione migliore è di utilizzare un template strumento, frammenti di codice, o creare un privato SetValue<T>(rif T backingField, valore T) che incapsula il setter.

private void SetValue<T>(ref T backingField, T value)
{
   if (backingField != value)
   {
      backingField = value;
      IsDirty = true;
   }
}

public string Name
{
   get
   {
      return _name;
   }
   set
   {
      SetValue(ref _name, value);
   }
}

L'altra alternativa potrebbe essere un generatore di codice come codesmith per automatizzare la creazione della proprietà.Questo sarebbe particolarmente utile se le proprietà sono la creazione di colonne in una tabella di database

Ti posso consigliare di utilizzare Enterprise Library per tale scopo.Applicazione dei criteri di Blocco fornisce l'infrastruttura per fare "qualcosa" (qualcosa = e ' possibile il codice sul proprio) ogni volta che si entra/esci un metodo per fare un esempio.È possibile controllare il comportamento con gli attributi.Prendo come un suggerimento di un andare nel dettaglio con la documentazione di enterprise library.

C'è un DefaultValueAttribute che può essere assegnato a una proprietà, questo è principalmente utilizzato dai designer di strumenti in modo che in grado di indicare quando una proprietà è stata modificata, ma, potrebbe essere un "ordinato" modo di descrivere ciò che il valore di default per una proprietà e, quindi, essere in grado di identificare se è cambiato.

Si avrebbe bisogno di utilizzare la Reflection per identificare le modifiche delle proprietà che non è in realtà che costoso a meno che non si sta facendo un sacco di esso!

Caveat:Non saresti in grado di dire se una proprietà era stato modificato da un non-valore predefinito predefinito.

Direi che il modo migliore per risolvere questo problema è quello di utilizzare Aspect-Oriented Programming (AOP).Stuoie Helander fatto un scrivere su questo InfoQ.L'articolo è un po ' disordinato, ma è possibile seguire.Ci sono un certo numero di prodotti diversi, che non AOP nel .Lo spazio in rete, mi raccomando PostSharp.

Se si va con gli Attributi, sono abbastanza certo dovrete arrotolare la logica dedurre che cosa significano e che cosa fare al riguardo.Qualunque cosa si utilizza la classe personalizzata oggetti hanno un modo di esecuzione di queste attributo azioni di controllo, preferibilmente durante la creazione dell'istanza.

In caso contrario, si sta guardando usando magari gli eventi.Ci si deve ancora aggiungere che l'evento ogni metodo set, ma i vantaggi che ci sarebbero non siete hard-codifica che cosa fare in merito sporco imposta su ogni proprietà e controllo, in un luogo, che cosa deve essere fatto.Che sarebbe, almeno, di introdurre un po ' più di codice di ri-uso.

ContextBound oggetto.Se si crea una classe che estende contesto vincolato oggetto e si crea un ContextAttribute è possibile intercettare le chiamate fatte alla proprietà e impostare il IsDirty..NET creerà un proxy per la tua classe, in modo che tutte le chiamate di andare su qualcosa come un remoting lavandino.

Il problema di questo approccio, però, è che la delega può essere invocato quando chiamato esternamente.Ti faccio un esempio.

class A
{
    [Foo]
    public int Property1{get; set;}
    public int Property2{get {return variable;} set{ Property1 = value; variable = value; }
}

Quando proprietà1 viene chiamato da un'altra classe, il proxy potrebbe essere richiamate.Ma se un'altra classe chiamate property2, anche se il set di property2 sarà chiamata in proprietà1 nessun proxy verrà richiamato, (un proxy non è necessario quando sei in classe stessa).

C'è un sacco di codice di esempio di utilizzo di ContextBoundObjects, guardare dentro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top