It is usually a recommended practice to have Value-Object base-class so we can have common functionality which can be used by all of our value-object classes. Typically, comparison methods or any other common subject for Value-Objects, should be included here.
Below I show a sample Value-Object Base-Class:
| public class <strong><span style="font-size: x-small">ValueObject<TValueObject></span></strong> : IEquatable<TValueObject><br /> where TValueObject : ValueObject<TValueObject><br />{ |
| <br />public bool <strong>Equals(</strong>TValueObject other)<br />{<br /> if ((object)other == null)<br /> return false;<br /> <br /> //compare all public properties<br /> PropertyInfo[] publicProperties = this.GetType().GetProperties();<br /> <br /> if ((object)publicProperties != null<br /> &&<br /> publicProperties.Any())<br /> {<br /> bool result = true;<br /> foreach (var item in publicProperties)<br /> {<br /> //compare two values using default equatable method<br /> if (!item.GetValue(this, null).Equals(item.GetValue(other, null)))<br /> {<br /> result = false;<br /> break;<br /> }<br /> }<br /> <br /> return result;<br /> }<br /> else<br /> return true;<br />}<br /> <br />public override bool <strong>Equals(</strong>object obj)<br />{<br /> if ((object)obj == null)<br /> return false;<br /> <br /> ValueObject<TValueObject> item = obj as ValueObject<TValueObject>;<br /> <br /> if ((object)item != null)<br /> return Equals((TValueObject)item);<br /> else<br /> return false;<br /> <br />}<br /> <br />public override int <strong>GetHashCode()</strong><br />{<br /> int hashCode = 31;<br /> bool changeMultiplier = false;<br /> int index = 1;<br /> <br /> //compare all public properties<br /> PropertyInfo[] publicProperties = this.GetType().GetProperties();<br /> <br /> if ((object)publicProperties != null<br /> &&<br /> publicProperties.Any())<br /> {<br /> foreach (var item in publicProperties)<br /> {<br /> object value = item.GetValue(this, null);<br /> <br /> if ((object)value != null)<br /> {<br /> <br /> hashCode = hashCode * ((changeMultiplier) ? 59 : 114) + value.GetHashCode();<br /> <br /> changeMultiplier = !changeMultiplier;<br /> }<br /> else<br /> hashCode = hashCode ^ (index * 13);//only for support {"a",null,null,"a"} <> {null,"a","a",null}<br /> }<br /> }<br /> <br /> return hashCode;<br />}<br /> <br />public static bool <strong><span style="font-size: x-small">operator ==</span></strong>(ValueObject<TValueObject> x, ValueObject<TValueObject> y)<br />{<br /> // If both are null, or both are same instance, return true.<br /> if (System.Object.ReferenceEquals(x, y))<br /> {<br /> return true;<br /> }<br /> <br /> // If one is null, but not both, return false.<br /> if (((object)x == null) || ((object)y == null))<br /> {<br /> return false;<br /> }<br /> <br /> // Return true if the fields match:<br /> <br /> return x.Equals(y);<br /> <br />}<br /> <br />public static bool <span style="font-size: x-small"><strong>operator !=</strong></span>(ValueObject<TValueObject> x, ValueObject<TValueObject> y)<br />{<br /> return !(x == y);<br />}<br />} |