Laden...

Automatische Properties: Eigener Setter ohne zugehörige private Variable. Möglich?

Erstellt von Ares vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.445 Views
A
Ares Themenstarter:in
167 Beiträge seit 2005
vor 10 Jahren
Automatische Properties: Eigener Setter ohne zugehörige private Variable. Möglich?

Hallo,

Eine Klasse hat ein Feld "Datum":


public class MyClass {
   public DateTime Date { get; set; }
}

Ich würde nun gerne im Setter des Feldes irgendwelchen zusätzlichen Code ausführen, der mit dem eigentlichen Setzen des Feldes nichts zu tun hat:


public class MyClass {
   public DateTime Date { 
      get; 
      set {
         MachIrgendWas();
      }
}

Wenn ich dies so ausführe, wird zwar MachIrgendWas() korrekt aufgerufen, Date hat aber nach der Zuweisung keinen neuen Wert. Wird der Setter explizit angegeben muss scheinbar auch die Zuweisung explizit erfolgen:


public class MyClass {
   private DateTime date;
   public DateTime Date { 
      get { return date; }
      set {
         date = value;
         MachIrgendWas();
      }
}

Man muss also zuätzlich eine private Variable einfügen, der dann im Setter explizit der Wert zugewiesen wird und die dann auch im Getter verwendet wird.

Das ist zwar kein Drama, aber auch nicht schön. Ich benötige diese private Variable nirgendwo sonst. Ich fände es daher besser, wenn diese nur vom Compiler intern verwendet wird und nicht in meinem Code auftraucht. Ist das möglich?

6.911 Beiträge seit 2009
vor 10 Jahren

Hallo Ares,


public DateTime Date { get; set; }

ist nur "Syntax-Zucker" vom Compiler, der das private "backing field" automatisch generiert. Wenn diese Konvention verlassen wird, so muss das private Feld selbst erstellt und verwaltet werden.

Möglich, aber nicht empfehlenswert, ist es auf das vom Compiler erstellte Feld per Reflection zuzugreifen. Das ist aber unperformant und außerdem kann das Muster, wie der Name für das erstellte Feld gewählt wird, sich in einer neuen Compiler-Version auch ändern.

Ausgehend von INotifyPropertyChanged gibt es ein paar nette Lösungen die etwas ähnliches ermöglichen. Falls das eine Möglichkeit wäre, siehe z.B. [Artikel] INotifyPropertyChanged implementieren den Bereich mit DependsUponAttribute - das lässt sich auch auf Methoden-Aufrufe erweitern.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

849 Beiträge seit 2006
vor 10 Jahren

Hi,

für solche Sachen ist PostSharp eine mächtiges Tool. Ich würde es nur deswegen nicht einführen, aber wenn Dir noch mehrere Anwendungsfälle einfallen, ist es eine Überlegung wert.

Gruß

Jan

S
145 Beiträge seit 2013
vor 10 Jahren

Was soll auch "Machirgendwas" machen, wenn MachIrgendwas nixs mitbekommt das etwas neues zu machen ist?
Ein setter ist implizit nur ein Metohden Aufruf, das problem wird deine Machirgendwas Methode sein.
Die wahrscheinlich intern mit dem Feld irgendwas macht, weshalb es nur funktioniert wenn das Feld einen Wert hat.

6.911 Beiträge seit 2009
vor 10 Jahren

Hallo Spyke,

ich denke du hast das falsch verstanden. MachIrgendwas wird korrekt aufgerufen, aber der Wert der Date-Eigenschaft nicht geändert, was klar ist, da das durch die Eigenschaft gekapselte Feld nicht aktualisiert wird.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

S
145 Beiträge seit 2013
vor 10 Jahren

Ehrlich gesagt denke ich das ich es schon richtig verstanden habe.
Der Poster erwartet das irgendwas im setter passiert ohne verstanden zu haben was der setter wirklich ist.

Wie ich schon anmerkte der setter ist in wirklichkeit nixs anderes wie ein Methoden aufruf.
Nur ohne Änderung spezifischer Faktoren der Methoden wird diese immer das gleiche machen, und das scheint mir im Falle des Posters der Fall.

Aber ich denke wir meinem im Grunde das gleiche, du sprichst ja von der aktualisierung des Feldes, ich im Grund ja auch.
Ich verlagere das problem nur eher auf die "machIrgnedwas" Methode, die ja anscheinend hier hauptbestandteil ist, die im prinzip etwas mit dem felde machen will, obwohl dieses nicht wirklich aktuell ist.

Deswegen steht eher die Fragen im Raum, ist hier wirklich ein Setter Aurfuf einer Eigenschaft erforderlich oder sollte nicht eher die Methode mit entsprechenden Parametern aufgerufen werden.....

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo Spyke,

auch ich meine, dass du die Frage falsch verstanden hast. Natürlich ist ein Setter technisch gesehen nur eine Methode, aber im Fall von automatischen Properties eben eine automatisch implementierte. Was hinter der Frage des OP steckt, ist nun, ob man diese automatische Implementierung erweitern kann, z.B. dass zusätzlich eine eigene Methode aufgerufen wird, aber das automatische Verhalten erhalten bleibt. Aber das geht eben nicht.

Was die Methode tut oder ob sie Parameter bekommt, ist hier nebensächlich, weil es eben schon an der Grundvoraussetzung scheitert, die automatische Implementierung zu erweitern. Es ist eben so, dass man sich entscheiden muss, ob man die automatische Implementierung haben will, die man nicht erweitern kann oder ob man eine eigene Implementierung definiert, bei der man dann allerdings alles selber machen muss.

Eine Teillösung - nach der der OP explizit gefragt hat - wäre, wenn man wenigstens das automatische Backing Field ansprechen könnte. Dann könnte man für den Getter die automatische Implementierung verwenden und für den Setter eine eigene Implementierung in der man an geeigneter Stelle das Backing Field setzt. In diesem Fall würde man sich wenigstens noch die Deklaration eines eigenen Backing Fields und die Implementierung des Getters ersparen. Aber das geht wie gesagt auch nicht (abgesehen von der unschönen Reflection-Möglichkeit).

Insofern kann man als Regel festhalten: Den Automatismus kann man nur verwenden, wenn man in keinster Weise von dem Standard-Verhalten abweichen will. Wenn man auch nur minima vom Standard-Verhalten abweichen will, muss man auf den Automatismus ganz verzichten und alles selber ausprogrammieren (abgesehen von AOP-Möglichkeiten, wie PostSharp, die aber zusätzliche Werkzeuge und Bibliotheken erfordert).

herbivore