Created
November 21, 2017 19:50
-
-
Save CumpsD/e3ddb20262f4290997aa8aea7c6691b4 to your computer and use it in GitHub Desktop.
Value Objects Plumbing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ValueObjects | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Collections.Immutable; | |
using System.Linq; | |
public abstract class GuidValueObject<T> : DataTypeValueObject<T, Guid> where T : GuidValueObject<T> | |
{ | |
protected GuidValueObject(Guid id) : base(id) { } | |
} | |
public abstract class DateTimeValueObject<T> : DataTypeValueObject<T, DateTime> where T : DateTimeValueObject<T> | |
{ | |
protected DateTimeValueObject(DateTime date) : base(date) { } | |
} | |
public abstract class StringValueObject<T> : DataTypeValueObject<T, string> where T : StringValueObject<T> | |
{ | |
protected StringValueObject(string @string) : base(@string) { } | |
} | |
public abstract class IntValueObject<T> : DataTypeValueObject<T, int> where T : IntValueObject<T> | |
{ | |
protected IntValueObject(int number) : base(number) { } | |
} | |
public abstract class ByteArrayValueObject<T> : DataTypeValueObject<T, byte[]> where T : ByteArrayValueObject<T> | |
{ | |
public ImmutableArray<byte> ImmutableBytes => Value.ToImmutableArray(); | |
protected ByteArrayValueObject(byte[] bytes) : base(bytes) { } | |
} | |
public abstract class DataTypeValueObject<T, TDataType> : ValueObject<T> where T : ValueObject<T> | |
{ | |
protected TDataType Value { get; } | |
protected DataTypeValueObject(TDataType number) => Value = number; | |
public static implicit operator TDataType(DataTypeValueObject<T, TDataType> valueObject) => valueObject.Value; | |
protected override IEnumerable<object> Reflect() | |
{ | |
yield return Value; | |
} | |
} | |
// https://smellegantcode.wordpress.com/2009/06/09/generic-value-object-with-yield-return/ | |
public abstract class ValueObject<T> : IEquatable<T> where T : ValueObject<T> | |
{ | |
protected abstract IEnumerable<object> Reflect(); | |
public static bool operator ==(ValueObject<T> obj1, ValueObject<T> obj2) | |
{ | |
if (ReferenceEquals(obj1, obj2)) | |
return true; | |
if (ReferenceEquals(obj1, null)) | |
return false; | |
if (ReferenceEquals(obj2, null)) | |
return false; | |
return obj1.Equals(obj2); | |
} | |
public static bool operator !=(ValueObject<T> obj1, ValueObject<T> obj2) => !(obj1 == obj2); | |
public override bool Equals(object obj) | |
{ | |
if (ReferenceEquals(null, obj)) | |
return false; | |
if (ReferenceEquals(this, obj)) | |
return true; | |
if (obj.GetType() != GetType()) | |
return false; | |
return Equals(obj as T); | |
} | |
public bool Equals(T other) | |
{ | |
if (ReferenceEquals(null, other)) | |
return false; | |
if (ReferenceEquals(this, other)) | |
return true; | |
return Reflect().SequenceEqual(other.Reflect()); | |
} | |
public override int GetHashCode() | |
{ | |
int HashCodeAggregator(int hashCode, object value) => value == null | |
? hashCode | |
: hashCode ^ value.GetHashCode(); | |
return Reflect().Aggregate(36, HashCodeAggregator); | |
} | |
public override string ToString() | |
{ | |
object StringAggregator(object l, object r) => $"{l}, {r}"; | |
return Reflect().Aggregate(StringAggregator).ToString(); | |
//return $"{{ {Reflect().Aggregate(StringAggregator)} }}"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment