Sprache: C#
[u][b]Sinn[/b][/u]
Vergleicht zwei Objekte rekursiv auf [b]inhaltliche Gleichheit[/b].
Die Objekte gelten als gleich, wenn alle enthaltenen [b]Werte[/b](-typen) jeweils gleich sind.
[b]Verweistypen[/b] werden ebenfalls auf Werte-Ebene verglichen (Rekursion über Verweistypen).
Anders als beim Vergleichsoperator (operator==) oder der Funktion Equals(…) werden hier wirklich nur die Werte verglichen.
Ein Beispiel für ein [b]einfaches Operator-Overloading[/b] siehen unten.
[u][b]Erweiterungsmöglichkeiten[/b][/u]
Mit einer Zeile wie
if (diub.Text.Substring(sub_type.ToString(), 0, 31) == "System.Collections.Generic.List") {…} else {…}
lassen sich auch Vergleiche über [b]Listen[/b] oder [b]Arrays [/b] implementieren.
[u][b]Verwendung[/b][/u]
[code]
bool status;
class Sub {
public String Name;
public String Salutation;
}
class Foo {
public Sub NameData;
…
}
Foo Left, Right;
Left = new Foo();
Right = new Foo();
// Initialisierung
Left.NameData.Name = "Test";
Right.NameData.Name = "Test";
…
//Vergleich
status = diub.Generic.xType.CompareByValue(Left, Right);
[/code]
[u][b]Operator Overloading[/b][/u]
Damit lassen sich auch recht einfach die Vergleichsoperatoren ('==', '!=') überladen.
[code]
static public bool operator ==(Account Left, Account Right) {
bool status;
status = diub.Generic.xType.CompareByValue(Left, Right);
return status;
}
static public bool operator !=(Account Left, Account Right) {
bool status;
status = diub.Generic.xType.CompareByValue(Left, Right);
return !status;
}
[/code]
static public bool CompareByValue(Object Left, Object Right) {
bool status;
Type type, sub_type;
Object sub_left, sub_right;
status = true;
type = Left.GetType();
foreach (PropertyInfo pi in type.GetProperties()) {
sub_type = pi.PropertyType;
sub_left = pi.GetValue(Left, null);
sub_right = pi.GetValue(Right, null);
if (sub_type == typeof(System.String)) {
status &= (String)sub_left == (String)sub_right;
} else
if (diub.Text.Substring(sub_type.ToString(), 0, 31) == "System.Collections.Generic.List") {
} else {
if (sub_type.BaseType == typeof(System.Object)) {
status &= CompareByValue(sub_left, sub_right);
} else {
status &= sub_left.Equals(sub_right);
}
}
if (!status)
return false;
}
foreach (FieldInfo fi in type.GetFields()) {
sub_type = fi.FieldType;
sub_left = fi.GetValue(Left);
sub_right = fi.GetValue(Right);
if (sub_type == typeof(System.String)) {
status &= (String)sub_left == (String)sub_right;
} else
if (diub.Text.Substring(sub_type.ToString(), 0, 31) == "System.Collections.Generic.List") {
} else {
if (sub_type.BaseType == typeof(System.Object)) {
status &= CompareByValue(sub_left, sub_right);
} else {
status &= sub_left.Equals(sub_right);
}
}
if (!status)
return false;
}
return true;
}
static public bool CompareByValue(Object Left, Object Right) {
bool status;
Type type, sub_type;
Object sub_left, sub_right;
status = true;
type = Left.GetType();
foreach (PropertyInfo pi in type.GetProperties()) {
sub_type = pi.PropertyType;
sub_left = pi.GetValue(Left, null);
sub_right = pi.GetValue(Right, null);
if (sub_type == typeof(System.String)) {
status &= (String)sub_left == (String)sub_right;
} else
if (diub.Text.Substring(sub_type.ToString(), 0, 31) == "System.Collections.Generic.List") {
} else {
if (sub_type.BaseType == typeof(System.Object)) {
status &= CompareByValue(sub_left, sub_right);
} else {
status &= sub_left.Equals(sub_right);
}
}
if (!status)
return false;
}
foreach (FieldInfo fi in type.GetFields()) {
sub_type = fi.FieldType;
sub_left = fi.GetValue(Left);
sub_right = fi.GetValue(Right);
if (sub_type == typeof(System.String)) {
status &= (String)sub_left == (String)sub_right;
} else
if (diub.Text.Substring(sub_type.ToString(), 0, 31) == "System.Collections.Generic.List") {
} else {
if (sub_type.BaseType == typeof(System.Object)) {
status &= CompareByValue(sub_left, sub_right);
} else {
status &= sub_left.Equals(sub_right);
}
}
if (!status)
return false;
}
return true;
}
Alte URL:
/snippet/generischer-vergleich-zweier-objekte-auf-werte-ebene/1638