-
-
Save vkhorikov/3cd9ef2c5f802b6d181a79b9ede0ea1f to your computer and use it in GitHub Desktop.
Value Objects: when to create one?
This file contains 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
public struct DecimalGreaterThanZero : IEquatable<DecimalGreaterThanZero> | |
{ | |
private readonly decimal _value; | |
public DecimalGreaterThanZero(decimal value) | |
{ | |
if (CanCreate(value) == false) | |
throw new ArgumentException("Value must be greater than zero.", nameof(value)); | |
_value = value; | |
} | |
public static bool CanCreate(decimal d) | |
{ | |
return d > decimal.Zero; | |
} | |
private decimal ValueGreaterThanZero => _value == decimal.Zero ? 1 : _value; | |
public static implicit operator DecimalGreaterThanZero(decimal d) | |
{ | |
return new DecimalGreaterThanZero(d); | |
} | |
public static implicit operator decimal(DecimalGreaterThanZero decimalGreaterThanZero) | |
{ | |
return decimalGreaterThanZero.ValueGreaterThanZero; | |
} | |
public override bool Equals(object obj) | |
{ | |
if (!(obj is DecimalGreaterThanZero)) | |
return false; | |
return Equals((DecimalGreaterThanZero)obj); | |
} | |
public bool Equals(DecimalGreaterThanZero other) | |
{ | |
return ValueGreaterThanZero == other.ValueGreaterThanZero; | |
} | |
public static bool operator ==(DecimalGreaterThanZero a, DecimalGreaterThanZero b) | |
{ | |
return a.Equals(b); | |
} | |
public static bool operator !=(DecimalGreaterThanZero a, DecimalGreaterThanZero b) | |
{ | |
return !a.Equals(b); | |
} | |
public override int GetHashCode() | |
{ | |
return ValueGreaterThanZero.GetHashCode(); | |
} | |
} |
This file contains 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
DecimalGreaterThanZero value = 0; |
This file contains 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
decimal value2 = value1; // value1 is a DecimalGreaterThanZero |
This file contains 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
DecimalGreaterThanZero value = (DecimalGreaterThanZero)0; |
This file contains 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
public class DecimalGreaterThanZero : ValueObject<DecimalGreaterThanZero> | |
{ | |
private readonly decimal _value; | |
public DecimalGreaterThanZero(decimal value) | |
{ | |
if (CanCreate(value) == false) | |
throw new ArgumentException("Value must be greater than zero.", nameof(value)); | |
_value = value; | |
} | |
public static bool CanCreate(decimal d) | |
{ | |
return d > decimal.Zero; | |
} | |
public static explicit operator DecimalGreaterThanZero(decimal d) | |
{ | |
return new DecimalGreaterThanZero(d); | |
} | |
public static implicit operator decimal(DecimalGreaterThanZero decimalGreaterThanZero) | |
{ | |
return decimalGreaterThanZero._value; | |
} | |
protected override bool EqualsCore(DecimalGreaterThanZero other) | |
{ | |
return _value == other._value; | |
} | |
protected override int GetHashCodeCore() | |
{ | |
return _value.GetHashCode(); | |
} | |
} |
This file contains 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
public struct Money : IEquatable<Money> | |
{ | |
public int Amount { get; } | |
public CurrencySymbol Currency { get; } | |
public bool Equals(Money other) | |
{ | |
return Amount == other.Amount && Currency == other.Currency; | |
} | |
public override bool Equals(object obj) | |
{ | |
if (ReferenceEquals(null, obj)) | |
return false; | |
return obj is Money && Equals((Money)obj); | |
} | |
public override int GetHashCode() | |
{ | |
unchecked | |
{ | |
return (Amount * 397) ^ (int)Currency; | |
} | |
} | |
} |
This file contains 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
public struct Money(int Amount, CurrencySymbol Currency); |
This file contains 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
public abstract class ValueObject<T> | |
where T : ValueObject<T> | |
{ | |
public override bool Equals(object obj) | |
{ | |
var valueObject = obj as T; | |
if (ReferenceEquals(valueObject, null)) | |
return false; | |
return EqualsCore(valueObject); | |
} | |
protected abstract bool EqualsCore(T other); | |
public override int GetHashCode() | |
{ | |
return GetHashCodeCore(); | |
} | |
protected abstract int GetHashCodeCore(); | |
public static bool operator ==(ValueObject<T> a, ValueObject<T> b) | |
{ | |
if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) | |
return true; | |
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) | |
return false; | |
return a.Equals(b); | |
} | |
public static bool operator !=(ValueObject<T> a, ValueObject<T> b) | |
{ | |
return !(a == b); | |
} | |
} |
This file contains 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
public class DecimalGreaterThanZero : ValueObject<DecimalGreaterThanZero> | |
{ | |
private readonly decimal _value; | |
public DecimalGreaterThanZero(decimal value) | |
{ | |
if (CanCreate(value) == false) | |
throw new ArgumentException("Value must be greater than zero.", nameof(value)); | |
_value = value; | |
} | |
public static bool CanCreate(decimal d) | |
{ | |
return d > decimal.Zero; | |
} | |
private decimal ValueGreaterThanZero => _value == decimal.Zero ? 1 : _value; | |
public static implicit operator DecimalGreaterThanZero(decimal d) | |
{ | |
return new DecimalGreaterThanZero(d); | |
} | |
public static implicit operator decimal(DecimalGreaterThanZero decimalGreaterThanZero) | |
{ | |
return decimalGreaterThanZero.ValueGreaterThanZero; | |
} | |
protected override bool EqualsCore(DecimalGreaterThanZero other) | |
{ | |
return ValueGreaterThanZero == other.ValueGreaterThanZero; | |
} | |
protected override int GetHashCodeCore() | |
{ | |
return ValueGreaterThanZero.GetHashCode(); | |
} | |
} |
This file contains 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
public DecimalGreaterThanZero(decimal value) | |
{ | |
if (CanCreate(value) == false) | |
throw new ArgumentException("Value must be greater than zero.", nameof(value)); | |
_value = value; | |
} | |
public static bool CanCreate(decimal d) | |
{ | |
return d > decimal.Zero; | |
} |
This file contains 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
private decimal ValueGreaterThanZero => _value == decimal.Zero ? 1 : _value; |
This file contains 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
public class DecimalGreaterThanZero : ValueObject<DecimalGreaterThanZero> | |
{ | |
private readonly decimal _value; | |
public DecimalGreaterThanZero(decimal value) | |
{ | |
if (CanCreate(value) == false) | |
throw new ArgumentException("Value must be greater than zero.", nameof(value)); | |
_value = value; | |
} | |
public static bool CanCreate(decimal d) | |
{ | |
return d > decimal.Zero; | |
} | |
public static implicit operator DecimalGreaterThanZero(decimal d) | |
{ | |
return new DecimalGreaterThanZero(d); | |
} | |
public static implicit operator decimal(DecimalGreaterThanZero decimalGreaterThanZero) | |
{ | |
return decimalGreaterThanZero._value; | |
} | |
protected override bool EqualsCore(DecimalGreaterThanZero other) | |
{ | |
return _value == other._value; | |
} | |
protected override int GetHashCodeCore() | |
{ | |
return _value.GetHashCode(); | |
} | |
} |
This file contains 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
public static implicit operator DecimalGreaterThanZero(decimal d) | |
{ | |
return new DecimalGreaterThanZero(d); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment