ValueObject.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using Abp.Reflection;
  2. using System;
  3. using System.Linq;
  4. using System.Reflection;
  5. namespace Abp.Domain.Values
  6. {
  7. //Inspired from https://blogs.msdn.microsoft.com/cesardelatorre/2011/06/06/implementing-a-value-object-base-class-supertype-patternddd-patterns-related/
  8. /// <summary>
  9. /// Base class for value objects.
  10. /// </summary>
  11. /// <typeparam name="TValueObject">The type of the value object.</typeparam>
  12. public abstract class ValueObject<TValueObject> : IEquatable<TValueObject>
  13. where TValueObject : ValueObject<TValueObject>
  14. {
  15. public bool Equals(TValueObject other)
  16. {
  17. if ((object)other == null)
  18. {
  19. return false;
  20. }
  21. var publicProperties = GetPropertiesForCompare();
  22. if (!publicProperties.Any())
  23. {
  24. return true;
  25. }
  26. return publicProperties.All(property => Equals(property.GetValue(this, null), property.GetValue(other, null)));
  27. }
  28. public override bool Equals(object obj)
  29. {
  30. if (obj == null)
  31. {
  32. return false;
  33. }
  34. var item = obj as ValueObject<TValueObject>;
  35. return (object)item != null && Equals((TValueObject)item);
  36. }
  37. public override int GetHashCode()
  38. {
  39. const int index = 1;
  40. const int initialHasCode = 31;
  41. var publicProperties = GetPropertiesForCompare();
  42. if (!publicProperties.Any())
  43. {
  44. return initialHasCode;
  45. }
  46. var hashCode = initialHasCode;
  47. var changeMultiplier = false;
  48. foreach (var property in publicProperties)
  49. {
  50. var value = property.GetValue(this, null);
  51. if (value == null)
  52. {
  53. //support {"a",null,null,"a"} != {null,"a","a",null}
  54. hashCode = hashCode ^ (index * 13);
  55. continue;
  56. }
  57. hashCode = hashCode * (changeMultiplier ? 59 : 114) + value.GetHashCode();
  58. changeMultiplier = !changeMultiplier;
  59. }
  60. return hashCode;
  61. }
  62. public static bool operator ==(ValueObject<TValueObject> x, ValueObject<TValueObject> y)
  63. {
  64. if (ReferenceEquals(x, y))
  65. {
  66. return true;
  67. }
  68. if (((object)x == null) || ((object)y == null))
  69. {
  70. return false;
  71. }
  72. return x.Equals(y);
  73. }
  74. public static bool operator !=(ValueObject<TValueObject> x, ValueObject<TValueObject> y)
  75. {
  76. return !(x == y);
  77. }
  78. private PropertyInfo[] GetPropertiesForCompare()
  79. {
  80. return GetType().GetTypeInfo().GetProperties().Where(t => ReflectionHelper.GetSingleAttributeOrDefault<IgnoreOnCompareAttribute>(t) == null).ToArray();
  81. }
  82. }
  83. }