Ich habe eine Klasse, die 2 Instanzen derselben Objekte vergleicht und eine Liste ihrer Unterschiede erzeugt. Dazu werden die Schlüsselsammlungen durchlaufen und eine Reihe anderer Sammlungen mit einer Liste der Änderungen gefüllt (dies kann nach dem Anzeigen des folgenden Codes sinnvoller sein). Das funktioniert und erzeugt ein Objekt, das mich darüber informiert, was genau zwischen dem "alten" Objekt und dem "neuen" Objekt hinzugefügt und entfernt wurde.
Meine Frage / Sorge ist diese ... es ist wirklich hässlich, mit Tonnen von Schleifen und Bedingungen. Gibt es eine bessere Möglichkeit, dies zu speichern / zu erreichen, ohne sich so sehr auf endlose Gruppen fest programmierter Bedingungen zu verlassen?
Der angestrebte Rahmen ist 3.5.
Verwenden Sie .NET 3.5? Ich bin mir sicher, LINQ to Objects würde viel viel einfacher machen.
Eine andere Sache, über die Sie nachdenken sollten, ist, dass wenn Sie viel Code mit einem gemeinsamen Muster haben, wo sich nur ein paar Dinge ändern (zB "welche Eigenschaft vergleiche ich?"), dann ist das ein guter Kandidat für eine generische Methode ein Delegierter, der diesen Unterschied darstellt.
EDIT: Okay, jetzt wissen wir, dass wir LINQ verwenden können:
Schritt 1: Verschachtelung reduzieren Zuerst würde ich eine Verschachtelungsstufe herausnehmen. Statt:
%Vor%Ich würde tun:
%Vor%Early Returns wie diese können Code deutlich lesbarer machen.
Schritt 2: Suchen nach zu löschenden Dokumenten
Das wäre viel schöner, wenn Sie einfach eine Schlüsselfunktion für Enumerable.Intersect angeben könnten. Sie können einen Gleichheitsvergleich angeben, aber das Erstellen eines solchen ist selbst bei einer Dienstprogrammbibliothek ein Problem. Ah gut.
%Vor% Schritt 3: Entfernen der Dokumente
Verwenden Sie entweder die vorhandene foreach-Schleife, oder ändern Sie die Eigenschaften. Wenn Ihre Eigenschaften tatsächlich vom Typ List & lt; T & gt; Dann könnten Sie RemoveAll verwenden.
Schritt 4: Aktualisieren und Entfernen von Benutzern
Eine Möglichkeit, die Dinge noch weiter zu vereinfachen, wäre die Implementierung eines IEqualityComparer mit UserId (und eines für Docs mit DocId).
Da Sie mindestens .NET 2.0 verwenden, empfehle ich Equals und GetHashCode ( Ссылка zu implementieren ) auf StepDoc. Als einen Hinweis darauf, wie es Ihren Code aufräumen kann, könnten Sie etwas wie folgt haben:
%Vor%mit diesem:
%Vor%Dies setzt voraus, dass oldDocs eine Liste von StepDoc ist.
Wenn sowohl StepDocs als auch StepUsers IComparable & lt; T & gt; implementieren und sie in Sammlungen gespeichert werden, die IList & lt; T & gt; implementieren, dann können Sie die folgende Hilfsmethode verwenden, um diese Funktion zu vereinfachen. Rufen Sie es einfach zweimal an, einmal mit StepDocs und einmal mit StepUsers. Verwenden Sie den Befehl beforeRemoveCallback, um die spezielle Logik zu implementieren, die für die Aktualisierung Ihrer Rollen verwendet wird. Ich gehe davon aus, dass die Sammlungen keine Duplikate enthalten. Ich habe Argument-Checks weggelassen.
%Vor%Hier ist ein Beispiel beforeRemoveCallback für Ihren Update-Code:
%Vor%Auf welchen Rahmen zielen Sie ab? (Dies wird einen Unterschied in der Antwort machen.)
Warum ist das eine Leerfunktion?
Sollte die Signatur nicht wie folgt aussehen:
%Vor%Wenn Sie die Traversierung der baumartigen Struktur ausblenden möchten, können Sie eine IEnumerator-Unterklasse erstellen, die die "hässlichen" Schleifenkonstrukte verbirgt und dann CompareTo interface verwendet:
%Vor%Allerdings bin ich mir überhaupt nicht sicher, dass dies alles besonders vereinfacht. Es macht mir nichts aus, die verschachtelten Traversalstrukturen zu sehen. Der Code ist verschachtelt, aber nicht komplex oder besonders schwer zu verstehen.
Die Verwendung mehrerer Listen in foreach ist einfach. Tun Sie dies:
%Vor%Es funktioniert ähnlich wie es für foreach ist (TextBox t in col & amp; & amp; TextBox d in des)
Tags und Links c# loops refactoring condition