Dictionary wird ohne Zuweißung einfach geändert

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von n1nja.

    Dictionary wird ohne Zuweißung einfach geändert

    Hallo Leute,

    ich habe mal aus Langeweile ein Dateivergleichstool geschrieben.
    Das soll Dateien vor und nach einer Aktion (zb. Installation) überprüfen und auswerten.

    Bis heute ging alles perfekt. Bis ich auf die Suchfunktion der WinAPI hier im Forum gestoßen bin.

    Ich habe 2 Dictionary´s.
    Eines wird davor gefüllt und eins danach.
    Jedoch sobald ich das zweite fülle und sich zb eine Datei ändert (hinzufügen, löschen etc) dann wird mir des erste wieder überschrieben. Ich hab keine Ahnung wo das sein soll.
    Hab schon alles versucht, Haltepunkte gesetzt, aber konnte keinen Fehler finden.

    Hier mal die Such-Methoden:
    Die wird aufgerufen wenn ein Button geklickt wird zum ersten Scannen.

    C#-Quellcode

    1. string pattern = textBox_pattern.Text;
    2. listView_files.Items.Clear();
    3. GUIenabled(false);
    4. button_startmon.Enabled = false;
    5. bool useapi = (checkBox_api.Checked) ? true : false;
    6. await Task.Run(() =>
    7. {
    8. foreach (int i in DriveSearch)
    9. {
    10. string di = OnlineDrives[i];
    11. if (useapi)
    12. {
    13. int files = 0;
    14. int folders = 0;
    15. long size = 0;
    16. ForList = APISearch.EnumerateFilesystem(di, ref files, ref folders, ref size); //hier das erste Dictionary
    17. }
    18. else
    19. {
    20. GetFiles(di, pattern);
    21. }
    22. }
    23. });


    ... und die hier wird aufgerufen, wenn der Benutzer die Anaylse stoppt.

    C#-Quellcode

    1. string pattern = textBox_pattern.Text;
    2. bool useapi = (checkBox_api.Checked) ? true : false;
    3. GUIenabled(false);
    4. await Task.Run(() =>
    5. {
    6. foreach (int i in DriveSearch)
    7. {
    8. string di = OnlineDrives[i];
    9. if (useapi)
    10. {
    11. int files = 0;
    12. int folders = 0;
    13. long size = 0;
    14. AfterList = APISearch.EnumerateFilesystem(di, ref files, ref folders, ref size);
    15. }
    16. else
    17. {
    18. SecondGetFiles(di, pattern);
    19. }
    20. }
    21. });
    22. Analysefiles();


    Die "ForList" bleibt solange richtig mit den Daten gefüllt, bis zu den Punkt wo AfterList zugewießen wird.
    Wenn ich es über meine normale Suchfunktion mache, dann funktioniert es.
    Ich bin wirklich ratlos.

    n1nja schrieb:

    dann wird mir des erste wieder überschrieben.
    Ich denke mal, Du verwendest dieselben Instanzen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Verstehe nicht ganz?!

    Werden beide davor instanziert.

    C#-Quellcode

    1. Dictionary<string, string> ForList = new Dictionary<string, string>();
    2. Dictionary<string, string> AfterList = new Dictionary<string, string>();


    Ah, ich glaube, ihr habt mich auf die Lösung gebracht.
    Die "APISearch" ist eine static Klasse.

    Ich werde die Klasse mal abändern und instanzier vor jeden Suchen, die Klasse selbst neu.
    Versuch mal die Werte aus dem ApiSearch Ergebnis in die ForList zu kopieren, statt direkt das Ergebnis zuzuweisen. Wenn es dann keine Probleme mehr gibt liegt es wohl an dem was Thunderbolt gesagt hat.

    Er meint es so:
    Wenn die ApiSearch-Methode nicht bei jedem Aufruf ein neues Dictionary instanziert, sondern sich ein bestehendes Objekt irgendwoher nimmt, dann verweist die ForList auf ebendieses Objekt, dass bei einem erneuten Aufruf wieder verändert wird. Weist du AfterList wiederum das Ergebnis zu, so zeigen ForList und AfterList effektiv auf dasselbe Objekt.

    n1nja schrieb:

    instanzier vor jeden Suchen, die Klasse selbst neu.

    Es würde reichen, wenn ​EnumerateFilesystem immer ein neues ​Dictionary zurückgibt. Deine Klasse kann statisch bleiben.
    Mit freundlichen Grüßen,
    Thunderbolt

    Thunderbolt schrieb:

    immer ein neues Dictionary zurückgibt


    Das ist die Klasse:

    C#-Quellcode

    1. Dictionary<string, string> ffiles = new Dictionary<string, string>();
    2. public Dictionary<string, string> EnumerateFilesystem(string rootDir, ref int files, ref int folders, ref long fullsize)
    3. {
    4. ffiles.Clear();
    5. unsafe
    6. {
    7. recursiv(rootDir);
    8. }
    9. return ffiles;
    10. }

    Also ist das hier dann der Fehler?
    Ich muss die Instanz von "ffiles" und mit new returnen?

    Ich find es komisch, das ich bis hier her noch nie Probleme damit gehabt habe;)

    n1nja schrieb:

    Also ist das hier dann der Fehler?
    Jou.
    Pack die Deklaration und Instanziierung in die Prozedur.

    C#-Quellcode

    1. public Dictionary<string, string> EnumerateFilesystem(string rootDir, ref int files, ref int folders, ref long fullsize)
    2. {
    3. Dictionary<string, string> ffiles = new Dictionary<string, string>();
    4. unsafe
    5. {
    6. recursiv(rootDir);
    7. }
    8. return ffiles;
    9. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    In der Prozedur recursiv füge ich die Daten hinzu.
    Deshalb hab ich das global deklariert.

    Wie wäre es am schönsten dann hier zu arbeiten?

    MIttlerweile hab ich das Problem über die Klasse selbst geregelt.
    Aber das verbraucht ja viel mehr Resourcen als wenn ich nur das Dictionary neu instanziere oder?
    Dann übergib der Methode recursiv noch das Dictionary. Oder du nutzt Lambdas. Das kann dann auch auf die Variable zugreifen:

    C#-Quellcode

    1. void x() {
    2. int num = 42;
    3. Console.WriteLine(num);
    4. var lambda = () => {
    5. Console.WriteLine(num);
    6. num = 7;
    7. };
    8. lambda();
    9. Console.WriteLine(num);
    10. }


    BTW: recursiv wäre Denglisch von rekursiv. Ich hätte z. B. recurse gewählt.
    Mit freundlichen Grüßen,
    Thunderbolt

    n1nja schrieb:

    als wenn ich nur das Dictionary neu instanziere

    RodFromGermany schrieb:

    Ich denke mal, Du verwendest dieselben Instanzen.
    Das ist der Unterschied.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!