我想避免对以下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
,我将得到{{1} }的状态为SomeId
。
什么是最好的解决方案?我什至应该在乎吗?
当然可以这样做:
Value = null
...但是,每当我访问此属性时,该附加的null检查都会困扰我。
答案 0 :(得分:1)
你应该在乎吗?是的,我想是这样。创建零初始化的结构(default(SomeId)
,new SomeId()
,new SomeId[n]
)非常容易,并且该结构在该状态下在语义上是无效的。
您有几种选择:
null
,并根据需要将字段设置为string.Empty
。从技术上讲,这是一种带有副作用的吸气剂(即使数据是封装的),有些人对此有强烈的意见,但是您也可以将其称为延迟初始化。ImmutableArray<T>
。