Frage

Ich habe eine Klasse mit einem Bündel von Eigenschaften, die wie folgt aussehen:

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

Es wäre viel einfacher, wenn ich mich verlassen konnte auf C # 3.0, um den Sicherungsspeicher für diese zu erzeugen, aber gibt es eine Möglichkeit, die IsDirty = true auszuklammern; so dass ich meine Eigenschaften so etwas schreiben kann und immer noch das gleiche Verhalten bekommen:

[MakesDirty]
public string Name { get; set; }
War es hilfreich?

Lösung

Nein. Nicht ohne wesentlich mehr (arkanen?) Das Schreiben von Code als die ursprüngliche Version (Sie müssten Reflektion verwenden für das Attribut auf dem Grundstück zu überprüfen und was nicht .. habe ich es erwähnt sein ‚langsamer‘) .. Dies ist die Art von Doppelarbeit kann ich mit leben.

MS hat den gleichen Bedarf an Ereignisse erhöhen, wenn eine Eigenschaft geändert wird . INotifyPropertyChanged, die eine wichtige Schnittstelle für Änderungsbenachrichtigungen ist. Jede Implementierung ich noch gesehen habe tut

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

Wenn es möglich wäre, würde ich diese smarten Jungs bei MS Figur hatte schon so etwas wie das an der richtigen Stelle ..

Andere Tipps

Sie könnten versuchen, einen Code-Schnipsel einrichten, um es einfach diejenigen zu schaffen.

Wenn Sie wirklich diesen Weg gehen wollen, zu ändern, was der Code ein Attribut nicht verwenden, gibt es einige Möglichkeiten, es zu tun, und sie alle sind auf AOP (Aspect Oriented Programming) bezogen. Schauen Sie sich Postsharp , die ein aftercompiler ist, dass der Code in einem nach der Kompilierung Schritt ändern können. Zum Beispiel könnten Sie einen benutzerdefiniertes Attribut für Ihre Eigenschaften festgelegt (oder Aspekt, wie es in AOP genannt wird), den Code innerhalb Eigenschaft Setter einspritzt, die Ihre Objekte als schmutzig markiert. Wenn Sie einige Beispiele wollen, wie dies erreicht ist, können Sie überprüfen ihre Tutorials .

Aber Vorsicht mit AOP und weil Sie genauso einfach mehr Probleme schaffen können es verwenden, dass Sie versuchen, nicht zu lösen, wenn verwendet rechts.

Es gibt mehr AOP-Frameworks gibt einige mit Post Kompilierung und einige mit der Methode Abhörmechanismen, die in .NET vorhanden sind, die später einige Performance-Nachteile gegenüber dem ersten.

Nein, wenn Sie die automatische Eigenschaften verwenden Sie haben keine Kontrolle über die Umsetzung. Die beste Option ist ein Templating-Tool, Code-Schnipsel zu verwenden oder ein eigenes SetValue<T> (ref T backingField, T-Wert), die die Setter-Logik kapselt erstellen.

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);
   }
}

Die andere Alternative könnte ein Code-Generator wie Codesmith sein, die Eigenschaften zu automatisieren zu schaffen. Dies wäre besonders nützlich, wenn die Eigenschaften, die Sie erstellen, sind Spalten in einer Datenbanktabelle

kann ich empfehlen Enterprise Library zu diesem Zweck zu verwenden. Politik Application Block liefert die Infrastruktur zu tun „etwas“ (etwas = Sie, dass auf Ihrem eigenen Code können), wenn Sie öffnen / schließen ein Verfahren zum Beispiel. Sie können das Verhalten mit Attributen steuern. Nehmen Sie das als Hinweis eines ins Detail geht mit der Dokumentation von Enterprise Library.

Es gibt eine Default, die ein Objekt zugeordnet werden kann, dies in erster Linie durch die Designer-Tools verwendet wird, so können sie angeben, wenn eine Eigenschaft geändert wurde, aber, könnte es zu beschreiben, was den Standardwert ein „ordentlich“ Weg für eine Eigenschaft ist, und damit identifizieren zu können, wenn es sich verändert hat.

Sie müssen Reflexion verwenden Eigenschaftsänderungen zu identifizieren - was nicht wirklich ist , die teuer, es sei denn Sie viele es tun

Caveat. Sie würden nicht in der Lage sein zu sagen, ob eine Eigenschaft zurück von einem Nicht-Standardwert auf den Standard eines geändert worden war

Ich würde sagen, dass der beste Weg, dies zu lösen, ist Aspect-Oriented Programming (AOP) zu verwenden. Mats Helander hat einen aufzuschreiben rel="nofollow auf InfoQ . Der Artikel ist ein bisschen chaotisch, aber es ist möglich zu folgen. Es gibt eine Reihe von verschiedenen Produkten, die AOP in .NET Raum der Fall ist, empfehle ich Postsharp.

Wenn Sie mit Attributen gehen Sie, ich bin ziemlich sicher, Sie müssen zu rollen eigene Logik abzuleiten, was sie bedeuten und was sie tun. Was auch immer Ihre eigene Klasse Objekte mithilfe muß eine Möglichkeit hat, von der Durchführung dieses Attribute Aktionen / Schecks, vorzugsweise bei Instanziierung.

Ansonsten sind Sie betrachtend mit vielleicht Veranstaltungen. Sie würden immer noch um das Ereignis zu jedem Set-Methode hinzufügen müssen, aber der Nutzen würde es Sie nicht hart codierte, was auf jede Eigenschaft über schmutzige Sätze zu tun und kann steuern, an einem Ort, was getan werden muss. Das wäre, zumindest, stellt ein bisschen mehr Code Wiederverwendung.

ContextBound Objekt. Wenn Sie eine Klasse erstellen, die den Kontext gebunden Objekt erweitert und Sie erstellen eine Context können Sie die Anrufe abfangen zu einer solchen Eigenschaft gemacht und die IsDirty gesetzt. .NET einen Proxy auf Ihre Klasse erstellen, so dass alle Anrufe gehen über so etwas wie ein Remote Waschbecken.

Das Problem mit einem solchen Ansatz ist aber, dass Ihr Proxy nur aufgerufen werden, wenn extern aufgerufen. Ich gebe Ihnen ein Beispiel.

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

Wenn property1 von einer anderen Klasse aufgerufen wird, würden Ihre Proxy aufgerufen. Aber wenn eine andere Klasse property2 nennt, auch wenn die Menge der property2 in property1 wird kein Proxy aufgerufen rufen wird, (ein Proxy ist nicht notwendig, wenn Sie in der Klasse sind selbst).

Es gibt Code viel Probe gibt ContextBoundObjects verwenden, schauen hinein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top