Laden...

Key eines Dictionary-Properties im getter/setter ermitteln?

Erstellt von citizen.ron vor 18 Jahren Letzter Beitrag vor 18 Jahren 2.459 Views
citizen.ron Themenstarter:in
432 Beiträge seit 2005
vor 18 Jahren
Key eines Dictionary-Properties im getter/setter ermitteln?

hallo leute,

folgender code stellt ein Property einer Klasse dar:

 
private Dictionary<string, object> _Field;
public  Dictionary<string, object> Field
{
   get { return _Field; }
   set 
   { 
      _Field = value; 
      _Dirty = true;
   }
}

kann ich innerhalb des setters irgendwie herausbekommen, welcher key gerade verwendet wurde, um den dictionary eintrag zu ändern/bekommen?
value bzw. _Field sind ja insgesamt vom Typ Dictionary<...> und lassen mich per Codeeditor nur an die Eigenschaften des ganzen Dictionary (also z.B. Keys, Values, etc..) ich möchte aber wissen, ob es möglich ist, den **einen **key zu bekommen, der von ausserhalb gerade verwendet wurde

Nochmal konkreter: bei der von ausserhalb der Klasse erfolgenden Anweisung:

myClass.Field["Nachname"] = "Duck";

möchte ich innerhalb des setters erfahren, dass als key **"Nachname" **angegeben wurde.

geht das überhaupt?

danke

gruß
ron

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo citizen.ron,

das Dictionary ist ein eigenständiges Objekt. Da es keinen Event anbietet, dass irgendwas geändert wurde, hast du keine Chance in deiner Klasse Änderungen an dem Dictionary mitzubekommen.

Ich sehe zwei Wege:

  1. Benutze statt einer Property einen Indexer.
  2. Schreibe deine eigene Dictionary-Klasse mit einem entsprechenden Event.

herbivore

citizen.ron Themenstarter:in
432 Beiträge seit 2005
vor 18 Jahren
Setter im Dictionary property wird nicht durchlaufen?

hallo zusammen,

@herbivore: danke für die antwort, genau diese beiden varianten hatte ich befürchtet...

nun aber ein anderes problem: ich habe nämlich festgestellt, dass eine setter methode eines properties vom typ dictionary niemals durchlaufen wird.

kann das jemand verifizieren (und ggf. erklären) ?

Nachstehend das Property:

 
private Dictionary<string, object> _Field;
public  Dictionary<string, object> Field
{
   get { return _Field; }
   set 
   {// wird nie durchlaufen 
      _Field = value; 
      _Dirty = true;
   }
} 

und hier der befehl von aussen:

_BusinessObject.Field["Nachname"] = "Duck";

debugging zeigt:
der getter wird durchlaufen, der setter nicht!

hä?

bin für jede hilfe dankbar. ich will eigentlich weg nummer 3 vermeiden: schreibe eine methode namens SetField(string keyName, object value) {...} 😦

gruß
ron

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo citizen.ron,

warum sollte bei _BusinessObject.Field["Nachname"] = "Duck" dein Setter durchlaufen werden? _BusinessObject.Field ruft das Dictionary-Objekt ab und dann wird der Setter des Indexers des Dictionary durchlaufen, um "Duck" zu setzen.

herbivore

T
210 Beiträge seit 2006
vor 18 Jahren

Der Setter ist natürlich für das ganze Dictionary. Wenn Du ein Element des Dictionarys setzt, wird der Setter fürs Dictionary natürlich nicht durchlaufen.

Gruß,
T-Man

S
8.746 Beiträge seit 2005
vor 18 Jahren

Um zu erreichen was du möchtest, musst du einen eigenen Indexer bereitsstellen und Field verbergen:

_BusinessObject["Nachname"] = "Duck";
citizen.ron Themenstarter:in
432 Beiträge seit 2005
vor 18 Jahren

aaaaaarrrrggggghhh!

melde mich wieder, wenn ich die indexer-kapitel in meinen c# büchern durch habe 😜

hatte bis jetzt tatsächlich geglaubt, mich drum drücken zu können...

danke für die antworten

ron

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo citizen.ron,

damit solltest du schnell durch sein. Ein Indexer ist ja nichts anderes als eine GetField (string keyName)- und SetField(string keyName, object value)-Methode in hübscher Syntax, so wie eine Property nicht anderes ist als eine GetField ()- und SetField(object value)-Methode in hübscher Syntax. Deine "Panik" ist also völlig unbegründet.

herbivore

citizen.ron Themenstarter:in
432 Beiträge seit 2005
vor 18 Jahren

so herbivore, hast mal wieder recht gehabt, indexer-panik war unbegründet.

muss aber für meine zwecke nochmal nachhaken (vielleicht hab ich´s auch noch nicht so ganz geblickt):
ich hab eine klasse BusinessObject. wie in obigen codebsp. mehrfach dargestellt, soll sie gewisse geschäftsmerkmale in form einer feldliste anbieten.

mach ich ein dictionary, wird der setter nicht durchlaufen beim ändern eines einzelnen wertes, das hatten wir gestern.

stelle ich jetzt einen indexer bereit, der demnach ja so aussehen müsste:

 
public object this[string columnName]
{
   get { return _Field[columnName]; }
   set 
   { 
      _Field[columnName] = value;
      this._Dirty = true;
      if (Modified != null) Modified();
   }
}

sagt mir der compiler an anderer stelle beim aufruf:

_BusinessObject["Nachname"] = "Duck";

Indizierung mit [] kann nicht auf einen Ausdruck vom Typ "Casa.PI.IBusinessObject" angewendet werden.

die ganze klasse soll ja eigentlich auch nicht aufzählbar sein.

würde ich jetzt statt eines dictionary eine eigene klasse mit indexer für das Property Field verwenden, hätte ich doch aber das problem, dass ich in der setter methode des indexers von Field ja nicht auf Eigenschaften der übergeordneten Klasse draufkann (also: BusinessObject).

irgendwie komm ich hier nicht weiter.

kann bitte nochmal jemand helfen...?

gruß
ron

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo citizen.ron,

ich weiß nicht, warum die Fehlermeldung kommt. Kannst du bitte mal die Fehlernummer angeben, also CSnnnn.

Ansonsten kannst du ja Klassendefinitionen auch ineinander schachteln oder internal verwenden. Beides wären in deinem Fall angemesse Vorgehensweisen.

herbivore

citizen.ron Themenstarter:in
432 Beiträge seit 2005
vor 18 Jahren

hi herbivore,

es schreibt hier the most happier programmer ever, es klappt:

BusinessObject implementiert bei mir die Schnittstelle IBusinessObject und der Indexer muss natürlich schon in der Schnittstelle entsprechend vorbereitet werden.

Nach Lektüre eines passenden Buchs und einem ersten Kaffee hab´ich´s kapiert und hingekriegt 🙂)))))))))

das wird ein guter tag!

in jedem fall aber: danke für den richtigen tip in the first place

gruß

ron