Feedback

C# - Generischer Vergleich zweier Objekte auf Werte-Ebene

Veröffentlicht von am 07.10.2012
(1 Bewertungen)
Sinn

Vergleicht zwei Objekte rekursiv auf inhaltliche Gleichheit.
Die Objekte gelten als gleich, wenn alle enthaltenen Werte(-typen) jeweils gleich sind.

Verweistypen 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 einfaches Operator-Overloading siehen unten.

Erweiterungsmöglichkeiten

Mit einer Zeile wie
if (diub.Text.Substring(sub_type.ToString(), 0, 31) == "System.Collections.Generic.List") {...} else {...}
lassen sich auch Vergleiche über Listen oder Arrays implementieren.

Verwendung

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);

Operator Overloading

Damit lassen sich auch recht einfach die Vergleichsoperatoren ('==', '!=') überladen.

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;
}
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;
}
Abgelegt unter Generic Compare.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!