Grundlagenfrage...

  • WPF

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von fichz.

    Grundlagenfrage...

    Hallo Leute und danke fürs reinschauen...

    nehmen wir mal an, wir hätten zwei Klassen, Klasse A und B. Jetzt stellt klasse A eine ObservableCollection zur Verfügung für die Klasse B mit irgend welchen Objekten.

    C#-Quellcode

    1. ​...
    2. private ObservableCollection<IrgendEinObjekt> _GetCollection = null;
    3. public ObservableCollection<IrgendEinObjekt> GetCollection
    4. {
    5. get
    6. {
    7. ...
    8. return _GetCollection;
    9. }
    10. }
    11. ...


    Klasse B greift es an einer Stelle ab:

    C#-Quellcode

    1. ...
    2. private ObservableCollection<IrgendEinObjekt> collectionKlasseB = null;
    3. public void IrgendEineMethode()
    4. {
    5. collectionKlasseB = ObjektVonKlasseA.GetCollection
    6. }
    7. ...


    Bis jetzt alles super... Jetzt ändert sich aber die Collection im Ojekt der Klasse A. Und hier fängt es an schwierig zu sein. Ich bin davon ausgegangen, dass ich keine neue Collection erstelle. Somit eigentlich nur die Adresse weiter reiche. Daraus vermutete ich, dass wenn sich die Collection im Objekt A ändert, ist die Änderung im Objekt B selbstverständlich gleich mit. Dem ist es nicht so... Es scheint eine Kopie zu sein. Kann mir jemand begründen warum und wie ich es so machen kann, dass beide Listen gleich bleiben am liebsten ohne eine Kopie. ?(

    Danke im Voraus.
    Moin,

    das funktioniert. Du musst irgend etwas machen, was das Verhalten beeinflusst.

    C#-Quellcode

    1. public partial class MainWindow : Window
    2. {
    3. public MainWindow()
    4. {
    5. InitializeComponent();
    6. TestB t = new TestB();
    7. }
    8. }
    9. public class TestA
    10. {
    11. public TestA()
    12. {
    13. ListA = new ObservableCollection<int>();
    14. for(int i = 0; i < 10; i++)
    15. {
    16. ListA.Add(i);
    17. }
    18. }
    19. private ObservableCollection<int> _ListA;
    20. public ObservableCollection<int> ListA
    21. {
    22. get { return _ListA; }
    23. set { _ListA = value; }
    24. }
    25. }
    26. public class TestB
    27. {
    28. public TestB()
    29. {
    30. TestA t = new TestA();
    31. _ListA = t.ListA;
    32. //Hier hat _ListA Items
    33. t.ListA.Clear();
    34. //Hier nicht mehr
    35. }
    36. private ObservableCollection<int> _ListA;
    37. }

    Gruß
    Christoph
    Moment... bei dir ist Klasse A ein Objekt in der Klasse B. Meine beiden Klassen sind keine Objekte von einander. Sondern sind separat.
    Aber selbst dann, müsste es trotzdem eigentlich funktionieren. Und es funktioniert eben nicht. Deswegen frage ich ja...

    Ich mach damit nichts. Ich muss das halt aktualisieren, damit die Aktualisierung durch kommt...
    Wie kommst Du darauf, dass Dir das irgendeine Adresse mitgibt? Meinst Du eine Referenz? Auf jeden Fall wird der Wert im Getter natürlich kopiert, wenn Du das machst (immer by value). Folglich musste Dir die Collection immer selbst aktualisieren, indem Du sie neu holst.
    Um Änderungen zu erfassen, gibt es das CollectionChanged-Event, das Du in Klasse B entsprechend abonnieren kannst.
    Ach ja, GetCollection ist supotimal, schließlich ist es ja eine Eigenschaft, die man dauernd abrufen kann, keine Methode. Collection wäre angebrachter.

    @Christoph1972 Und was ist an Deinem Code jetzt anders, als beim TE? Das ist ja genau dasselbe Verhalten. Und bei Dir ist doch ein Objekt der Klasse A auch in der Klasse B vorhanden, @EugenIS? Daher verstehe ich auch Deine Antwort nicht so ganz.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Es hat mich am Anfang auch etwas verwirrt.
    Deswegen habe ich versucht es mal nachzustellen. Es funktioniert sehr wohl wenn innerhalb von Klasse B eine Referenz der Klasse A existiert. Jedoch muss diese zB über den Konstruktor von der Klasse B übergeben werden.
    Spoiler anzeigen

    C#-Quellcode

    1. public class A
    2. {
    3. private ObservableCollection<string> liste;
    4. public ObservableCollection<string> Liste
    5. {
    6. get { return liste; }
    7. }
    8. public A()
    9. {
    10. liste = new ObservableCollection<string>();
    11. liste.Add("a");
    12. liste.Add("b");
    13. }
    14. }
    15. public class B
    16. {
    17. private A KlasseA;
    18. private ObservableCollection<string> listeIntern;
    19. public B(A klasseA)
    20. {
    21. KlasseA = klasseA;
    22. listeIntern = KlasseA.Liste;
    23. }
    24. }


    Wird nun im Programm eine Instanz der Klasse A erzeugt und diese beim Erstellen der Instanz von Klasse B mitübergeben, dann funktioniert es sehr wohl:
    Spoiler anzeigen

    C#-Quellcode

    1. ​public partial class MainWindow : Window
    2. {
    3. private A klasseA;
    4. private B klasseB;
    5. public MainWindow()
    6. {
    7. InitializeComponent();
    8. klasseA = new A();
    9. klasseB = new B(klasseA);
    10. }
    11. private void Button_Click(object sender, RoutedEventArgs e)
    12. {
    13. klasseA.Liste.Add("c");
    14. // Ab hier haben klassaA.Liste 3 Einträge und auch klasseB.listeIntern hat die gleichen Einträge.
    15. }
    16. }


    @Trade soweit ich weiß wird bei Referenztypen (auch mit by value) nicht die Instanz kopiert sondern nut der Zeiger, was aber eine Änderung der Collection an beiden Enden mit sich zieht (ist ja der selbe Zeiger).

    Das Problem an dem Post ist (wie leider viele von @EugenIS), dass hier ein kleines Fleckchen Code mit einer ungenauen Beschreibung vorhanden sind.
    Es würde um einiges hilfreicher sein, wenn nicht nur so Codefetzen geposten werden, sondern ein ganzes Beispiel an Klassen und wie diese verarbeitet werden. (Wie in diesem post zB)...

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    ich kenne es nur von Listen. Wenn ich eine Liste von 10 Objekten habe, und irgend wo einfach zuweise, ist es nicht kopiert. Probier doch mal selbst es aus. Der Christoph1972 hat schon recht. Das war auch meine Denke. Wenn du in einer der Listen was löschst, ist es in beiden weg. Eine Zuweisung ist keine Kopie... Wenn du eine Kopie haben möchtest muss du es mit for oder foreach schleife alle Elemente einzelnd neu erstellen und in die zweite liste neu einfügen. selbst bei den Elementen geht die Zuweisung nicht. selbst die musst du neu erstellen und dann variable für variable kopieren...
    Das war mir klar, dass dann ein Zeiger auf dieselbe Adresse vorhanden ist und das nicht kopiert wird. Allerdings hatte ich einen Denkfehler bei der Property, da müsste das natürlich auch so sein, sorry.
    Kannst Du mal, wie fichz sagte, ein direktes Beispiel posten? Vielleicht ist dort ja irgendwas anders?

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Eigentlich ist meine Frage gut genug formuliert. Die beiden beispiele Treffen es richtig gut... es sind nur die beiden klassen. wie ich es hinkriege die zu kopieren, ohne die kopiert zu haben ist mir ein rätsel... ich muss ja blöd genug sein, um irgend wo eine for oder foreach schleife laufen zu lassen, und die auch noch zu übersehen...
    Vorschlag:
    Erstelle ein kleines Projekt, wo du dein Problem nachstellen kannst und lade es hier auf VBP hoch.
    Am Besten wäre es die betroffenen ECHTEN Klassen und deren Verwendung hier zu posten. Und nicht irgendwelche erfundenen Klassen A und B.

    Ich vermute einfach, dass irgendwo im Ablauf ein Fehler ist, welcher durch diese "Klasse A und B" Inszenierung aber nicht nachvollziehbar ist. Zumindest für mich nicht.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten