Laden...

Referenzierungsmodell C#; Übergabe von Objekt -> änderungen nicht übernommen

Erstellt von Animal21 vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.334 Views
Thema geschlossen
A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 10 Jahren
Referenzierungsmodell C#; Übergabe von Objekt -> änderungen nicht übernommen

Hallo Freunde,

entweder werde ich verrückt oder ich verstehe das Referenzmodell von C# nicht ganz.

Ich habe ein Programm indem Konfiguration-Daten über ein Dialog A bearbeitet werden können.
Die Daten werden als DeepCopy() an das Dialog A übergeben, damit ich beim "Abbrechen" der Bearbeitung keine Arbeit habe alles wieder umzubiegen. (Modell BusinessObjekt)

In dem Dialog A werden die Daten in einer Tabelle angezeigt, per Doppelklick kann man nun ein spezielles Objekt in einem weiteren Dialog B bearbeiten, dabei wird das Objekt mit


Dialog_B.Objekt = Dialog_B.List[X]

übergeben.

Weiterhin habe ich in Dialog A die Events der Objekte registriert, um auf Änderungen des Models in der View zu reagieren.

Ändert nun Dialog_B die Daten vom übergebenen Objekt, so wird der EventHandler korrekt ausgeführt, aber die Daten in der Liste von Dialog A wurden NICHT geändert.

Sollte ich das Objekt mit ref üdergeben (ist mir gerade eingefallen und werde ich gleich testen).
Wenn ja warum, ich dachte, es werden immer Referenzen bei ReferenzObjekten übergeben und keine Kopien.

Grüße
Mario

656 Beiträge seit 2008
vor 10 Jahren

Du sagst doch selber, dass du eine DeepCopy erzeugst. Damit sollte auch klar sein, warum sich die Original-Objekte nicht ändern.

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo BhaaL,

ja, bei der Übergabe an Dialog A. Hier geht es aber um die Übergabe von Dialog A nach Dialog B.

Hallo Animal21,

ref zu verwenden ist Quatsch und bei Dialogen auch gar nicht (durchgängig) möglich. ref hat einen ganz anderen Zweck, siehe [Artikel] Parameter-Übergabemechanismen: call by value vs. call by reference (ref/out).

Du schreibst, "die Daten in der Liste von Dialog A wurden NICHT geändert". Das ist aber was ganz anderes, als das ab Dialog B übergebene Objekt hat sich nicht geändert. Vermutlich fehlt die Aktualisierung des GUIs.

Die Referenzsemantik und ihre Auswirkungen gehören allerdings zu den Grundlagen, siehe [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

herbivore

A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 10 Jahren

Hallo herbivore,

Danke für die Antwort. Es geht nicht um die View.

Ich habe mir den Vorgang im Debug-Modus angeschaut:

Dialog A übergibt beim Doppelklick das Objekt mit einer Zuweisung (s.o.).
Nach der Änderung und dem Klick auf den OK-Button von Dialog B, wird z.b. der Name des Objektes geändert und Dialog A bemerkt dies, da es sich das entsprechende Event registriert hat. Und an dieser Stelle wird die ListView aktualisiert.

Aber in der "DeepCopy" in Dialog A, die ich vom Ausgangs-Form habe und die an das Dialog B übergeben wurde, welches das Objekt manipuliert hat, wurde nichts geändert.


1. Dialog_A.List[Obj1, Obj2, Obj3];
2. forall(Obj in Dialog A.List)
          Obj.NameChanged += NameOfObjChanged;
3. Dialog_B.Obj = Dialog_A.List[1];

4. Dialog_B.Obj.Name = "neuer Name";

5. Dialog_A.NameOfObjChanged(...){
     //Änderung des Namen registriert
     //ListView aktualisieren
}

6. Dialog_A.List[1].Name ?= "alter name";

Ich hoffe, damit ist das Problem etwas verständlicher geworden.

grüße

A
Animal21 Themenstarter:in
144 Beiträge seit 2008
vor 10 Jahren

Eine Klasse.

Ich hab mein Problem lösen können; war mein Fehler.

Zum ersten habe ich ein "WorkingObj" und eine "ObjList" und den Fehler gemacht, dass das WorkingObj eine DeepCopy bekommt und dann erst die ObjList, wodurch das betreffende WorkingObj ein anderes war, als das ensprechende in der ObjList.
Ich muss zuerst die Liste mit DeepCopies füllen und dann ein Objekt daraus an das WorkingObj übergeben...

Zum zweiten habe ich nicht beachtet, dass in der Name-Property des Objekts erst das Event ausgelöst wird, und danach erst der neue Wert gesetzt wird (damit ich noch den alten Wert ins Event übergeben kann).

Dadurch konnte die Änderung in der Liste in Dialog A allerdings erst nach dem ausgelösten Event geändert werden. Habe das Debugging allerdings immer vorher abgebrochen, bzw. nicht weiterverfolgt, da ich einen Fehler gesehen habe...

Sorry für den Thread.

grüße

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo Animal21,

erst das Event ausgelöst wird, und danach erst der neue Wert gesetzt wird (damit ich noch den alten Wert ins Event übergeben kann).

irgendwas passt da nicht zusammen.

Ein Changed-Event sollte immer nach der Änderung geworfen werden (und auch nur dann, wenn sich der Wert tatsächlich geändert hat). Es ist normalerweise kein Problem, sich den Wert vor der Änderung zu merken, und das Event trotzdem erst danach zu feuern.

Wenn ein Event vor der Änderung gefeuert wird, sollte es (Before)Changing heißen. Dann braucht man den alten Wert aber nicht zu übergeben, weil man ihn ja noch abfragen kann. Stattdessen wäre hier für den EventHandler der neue Wert interessant.

Das nur am Rande.

herbivore

Thema geschlossen