Muster, um strukturierte Differenzen und Statistiken von Objekten zu erhalten oder um Diff-Werkzeuge zu erzeugen

8

Sagen wir, ich habe eine solche Struktur

%Vor%

Also enthält die Klasse Form die Liste der Felder, sagen wir, dass das Feld selbst mit einer solchen Struktur dargestellt wird

%Vor%

Die Field ist im Grunde eine zusammengesetzte Struktur, jede Field enthält die Liste der untergeordneten Felder. Die Struktur ist also hierarchisch. Auch Field verweist auf die Klasse FieldType .

%Vor%

Und am Ende haben wir einen Verweis auf DataType

%Vor%

Was ich erreichen möchte ist, den Unterschied einer solch komplexen Struktur zu bekommen, sagen wir, wenn ich irgendeine Art von Comparer habe, wird es mir einen strukturierten Unterschied für die ganze Form als eine Klasse geben, sagen wir DifferenceResult. Wenn ich strukturierten Unterschied sage, meine ich, dass es so etwas sein sollte.

  1. Unterschied für die Felder Form (Ausgabe Form hat Unterschiede im Feld Version (andere Farbe)
  2. Unterschiede für die Fields -Sammlung, einschließlich der Hierarchie der Felder zum bearbeiteten Feld
  3. Gleiches Verhalten für FieldType und DataType
  4. Ermitteln Sie das Entfernen und fügen Sie Field in Form hinzu (wahrscheinlich wird jeder Unterschied einen Typ haben)

Was ich gerade habe. Ich habe mit dem generischen Ansatz begonnen und versucht, ReflectionComparer zu verwenden, das die IEqualityComparer-Schnittstelle implementiert.

%Vor%

Und Difference class

%Vor%

Aber wahrscheinlich ist es nicht die Art, wie ich gehen möchte, weil ich Feld genauer vergleichen sollte unter Berücksichtigung, dass jedes Feld ID hat, die für verschiedene Formen auch unterschiedlich sein kann, und ich möchte mehr Kontrolle über den Vergleichsprozess nehmen . Für mich klingt es eher wie ein Diff-Tool.

Ich suche also nach einem guten Muster und einer ziemlich guten Struktur, um den Unterschied zum Client-Code zu veröffentlichen, der es leicht visualisieren kann?

    
Jevgenij Nekrasov 19.12.2012, 15:27
quelle

3 Antworten

1

Nachdem ich ein Bit untersucht und verschiedene Ressourcen verglichen habe, habe ich einen solchen Algorithmus implementiert.

  1. Nimm dein Objekt und konstruiere das Diagramm (benutze .GetType (). GetProperties () und füge jede Eigenschaft als Kindknoten deines Wurzelknotens hinzu. Der Schlüssel des Knotens ist der Name der Eigenschaft.
  2. Gehen Sie rekursiv, wenn Sie Eigenschaften eines benutzerdefinierten Typs oder IEnumerable erfüllen.
  3. Erstellen Sie einen Graphenvergleicher und vergleichen Sie zwei Graphen

Später werde ich meinen Code veröffentlichen und die Antwort aktualisieren.

    
Jevgenij Nekrasov 10.01.2013, 17:38
quelle
1

Da Ihre Klassen bereits sehr bekannt sind, würde ich folgende Dinge verwenden:

  • Eine IDiffable-Schnittstelle, die eine Klasse mit einer DiffWith (T other) -Klasse erzeugt und eine Aufzählung von Unterschieden zurückgibt. Es macht dann Sinn, einfach Ihren DiffWith in jeder Ihrer Klassen zu implementieren, was trivial sein sollte, da sie ziemlich fest sind.

  • Eine separate ReflectionDiff-Klasse (möglicherweise statisch), die wie Reflektoren mit der Reflektion verglichen wird. Dieser könnte Attribute verwenden, um beliebige Eigenschaften / Felder aufzulisten / zu ignorieren. Auf diese Weise können Sie eine Standard-Diff-Engine für die schnelle Implementierung von Unterschieden verwenden und genau den von Ihnen verwendeten Reflektionscode verwenden. Sie könnten einfach eine Implementierung von diff mit wie:

    haben %Vor%

Sie erhalten eine einzige Klasse mit dem ganzen schmutzigen Reflexionscode (der nicht wirklich benötigt wird) und können eine einfache Implementierung von DiffWith in jeder Ihrer diffablen Klassen haben.

    
Wam 20.12.2012 09:46
quelle
0

Nicht sicher, wie elegant Sie eine Lösung suchen, aber wenn Sie nur eine ziemlich schnelle Lösung mit minimalem Code wollten, dann vielleicht:

  1. serialisieren Sie Ihre Instanzen, um sie mit einem Textformat zu vergleichen (z. B. JSON mit JSON.NET)
  2. schreibe die serialisierten Objekte in Textdateien
  3. Starten Sie ein Diff-Tool, das die 2 Textdateien als Argumente übergibt (so etwas wie ExamDiff macht das leicht)

Wie ich schon sagte, ist dies eine schnelle Lösung, aber vielleicht gut genug für Ihre Bedürfnisse. Ansonsten sind Befehlszeilen-Diff-Tools verfügbar, die eine Unix-Stil-Diff-Datei ausgeben, für die Sie dann Ihren eigenen Visualizer schreiben könnten.

    
MarkG 21.12.2012 10:18
quelle