Я хочу избежать примитивной одержимости следующим struct
.Для этого есть две цели:
- сделать сигнатуры методов более честными
- гарантировать, что недопустимое значение не может существовать
Реализация:
public struct SomeId : IEquatable<SomeId>
{
public static readonly SomeId Empty = new SomeId(String.Empty);
private SomeId(string someId)
{
Value = someId;
}
public string Value { get; }
public static bool operator ==(SomeId left, SomeId right) => left.Equals(right);
public static bool operator !=(SomeId left, SomeId right) => !(left == right);
public static implicit operator string(SomeId id) => id.Value;
public override int GetHashCode() => Value.GetHashCode();
public override bool Equals(object obj) => Value.Equals(obj);
public bool Equals(SomeId other) => String.Equals(Value, other.Value, StringComparison.Ordinal);
public static SomeId? Create(string value)
{
if (String.IsNullOrWhiteSpace(value))
{
return new SomeId(value);
}
return null;
}
}
Довольно много кода, но все еще не идеально !Действительно, это решает основную проблему, заключающуюся в том, что я не буду передавать строки повсеместно, а буду давать методологически значимую подпись.
Тем не менее, я могу внедрить недопустимое значение в свое приложение, просто создав новый экземпляр с помощью default(SomeId)
- поскольку Value
имеет тип string
, я получу SomeId
в недопустимом состоянии с Value = null
.
Какое будет лучшее решение здесь?Должен ли я вообще беспокоиться?
Конечно, я мог бы сделать, например, это:
private string _value;
public string Value => _value ?? String.Empty
... но эта дополнительная нулевая проверка всякий раз, когда я получаю доступ к этому свойству, вызывает у меня проблемы.