Feedback

Generischer Vergleich zweier Objekte auf Werte-Ebene

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