{"id":493,"date":"2011-06-06T15:22:00","date_gmt":"2011-06-06T15:22:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/cesardelatorre\/2011\/06\/06\/implementing-a-value-object-base-class-supertype-patternddd-patterns-related\/"},"modified":"2011-06-06T15:22:00","modified_gmt":"2011-06-06T15:22:00","slug":"implementing-a-value-object-base-class-supertype-patternddd-patterns-related","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/implementing-a-value-object-base-class-supertype-patternddd-patterns-related\/","title":{"rendered":"Implementing a Value-Object Base class (Supertype pattern\u2013DDD patterns related)"},"content":{"rendered":"<p>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.<\/p>\n<p>Below I show a sample Value-Object Base-Class:<\/p>\n<pre>public class <strong><span style=\"font-size: x-small\">ValueObject&lt;TValueObject&gt;<\/span><\/strong> : IEquatable&lt;TValueObject&gt;<br \/>&nbsp;&nbsp;&nbsp; where TValueObject : ValueObject&lt;TValueObject&gt;<br \/>{<\/pre>\n<pre>&nbsp;&nbsp;&nbsp; <br \/>public bool <strong>Equals(<\/strong>TValueObject other)<br \/>{<br \/>&nbsp;&nbsp;&nbsp; if ((object)other == null)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br \/> <br \/>&nbsp;&nbsp;&nbsp; \/\/compare all public properties<br \/>&nbsp;&nbsp;&nbsp; PropertyInfo[] publicProperties = this.GetType().GetProperties();<br \/> <br \/>&nbsp;&nbsp;&nbsp; if ((object)publicProperties != null<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; publicProperties.Any())<br \/>&nbsp;&nbsp;&nbsp; {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool result = true;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (var item in publicProperties)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/compare two values using default equatable method<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!item.GetValue(this, null).Equals(item.GetValue(other, null)))<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = false;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br \/> <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;<br \/>&nbsp;&nbsp;&nbsp; }<br \/>&nbsp;&nbsp;&nbsp; else<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br \/>}<br \/> <br \/>public override bool <strong>Equals(<\/strong>object obj)<br \/>{<br \/>&nbsp;&nbsp;&nbsp; if ((object)obj == null)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br \/> <br \/>&nbsp;&nbsp;&nbsp; ValueObject&lt;TValueObject&gt; item = obj as ValueObject&lt;TValueObject&gt;;<br \/> <br \/>&nbsp;&nbsp;&nbsp; if ((object)item != null)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Equals((TValueObject)item);<br \/>&nbsp;&nbsp;&nbsp; else<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br \/> <br \/>}<br \/> <br \/>public override int <strong>GetHashCode()<\/strong><br \/>{<br \/>&nbsp;&nbsp;&nbsp; int hashCode = 31;<br \/>&nbsp;&nbsp;&nbsp; bool changeMultiplier = false;<br \/>&nbsp;&nbsp;&nbsp; int index = 1;<br \/> <br \/>&nbsp;&nbsp;&nbsp; \/\/compare all public properties<br \/>&nbsp;&nbsp;&nbsp; PropertyInfo[] publicProperties = this.GetType().GetProperties();<br \/> <br \/>&nbsp;&nbsp;&nbsp; if ((object)publicProperties != null<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; publicProperties.Any())<br \/>&nbsp;&nbsp;&nbsp; {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (var item in publicProperties)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; object value = item.GetValue(this, null);<br \/> <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((object)value != null)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br \/> <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hashCode = hashCode * ((changeMultiplier) ? 59 : 114) + value.GetHashCode();<br \/> <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; changeMultiplier = !changeMultiplier;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hashCode = hashCode ^ (index * 13);\/\/only for support {\"a\",null,null,\"a\"} &lt;&gt; {null,\"a\",\"a\",null}<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br \/>&nbsp;&nbsp;&nbsp; }<br \/> <br \/>&nbsp;&nbsp;&nbsp; return hashCode;<br \/>}<br \/> <br \/>public static bool <strong><span style=\"font-size: x-small\">operator ==<\/span><\/strong>(ValueObject&lt;TValueObject&gt; x, ValueObject&lt;TValueObject&gt; y)<br \/>{<br \/>&nbsp;&nbsp;&nbsp; \/\/ If both are null, or both are same instance, return true.<br \/>&nbsp;&nbsp;&nbsp; if (System.Object.ReferenceEquals(x, y))<br \/>&nbsp;&nbsp;&nbsp; {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br \/>&nbsp;&nbsp;&nbsp; }<br \/> <br \/>&nbsp;&nbsp;&nbsp; \/\/ If one is null, but not both, return false.<br \/>&nbsp;&nbsp;&nbsp; if (((object)x == null) || ((object)y == null))<br \/>&nbsp;&nbsp;&nbsp; {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br \/>&nbsp;&nbsp;&nbsp; }<br \/> <br \/>&nbsp;&nbsp;&nbsp; \/\/ Return true if the fields match:<br \/> <br \/>&nbsp;&nbsp;&nbsp; return x.Equals(y);<br \/> <br \/>}<br \/> <br \/>public static bool <span style=\"font-size: x-small\"><strong>operator !=<\/strong><\/span>(ValueObject&lt;TValueObject&gt; x, ValueObject&lt;TValueObject&gt; y)<br \/>{<br \/>&nbsp;&nbsp;&nbsp; return !(x == y);<br \/>}<br \/>}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>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 ValueObject&lt;TValueObject&gt; : IEquatable&lt;TValueObject&gt;&nbsp;&nbsp;&nbsp; where TValueObject : [&hellip;]<\/p>\n","protected":false},"author":362,"featured_media":12806,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[5,41],"class_list":["post-493","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cesardelatorre","tag-net-4-0","tag-ddd"],"acf":[],"blog_post_summary":"<p>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 ValueObject&lt;TValueObject&gt; : IEquatable&lt;TValueObject&gt;&nbsp;&nbsp;&nbsp; where TValueObject : [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/posts\/493","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/users\/362"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/comments?post=493"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/posts\/493\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/media\/12806"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/media?parent=493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/categories?post=493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/tags?post=493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}