假设该场景不允许实现不可变类型。按照这个假设,我想就如何正确设计一种在使用后变得不可变的类型提供意见/示例。
public class ObjectAConfig {
private int _valueB;
private string _valueA;
internal bool Consumed { get; set; }
public int ValueB {
get { return _valueB; }
set
{
if (Consumed) throw new InvalidOperationException();
_valueB = value;
}
}
public string ValueA {
get { return _valueA; }
set
{
if (Consumed) throw new InvalidOperationException();
_valueA = value;
}
}
}
当
ObjectA
使用ObjectAConfig
时:public ObjectA {
public ObjectA(ObjectAConfig config) {
_config = config;
_config.Consumed = true;
}
}
我不满意这是否行得通,我想知道是否有更好的模式(如所排除的那样,从设计开始就使
ObjectAConfig
不可变)。例如:
Once<T>
这样定义一个monad,使包装的值仅初始化一次吗? 最佳答案
有时您要实现的名称称为“popsicle immutability”-即您可以将其卡住。您当前的方法会奏效-实际上,我在很多地方都使用了这种模式。
您可以通过以下方式减少重复:
private void SetField<T>(ref T field, T value) {
if (Consumed) throw new InvalidOperationException();
field = value;
}
public int ValueB {
get { return _valueB; }
set { SetField(ref _valueB, value); }
}
public string ValueA {
get { return _valueA; }
set { SetField(ref _valueA, value); }
}
但是,还有另一种相关方法:构建器。例如,参加您现有的类(class):
public interface IConfig
{
string ValueA { get; }
int ValueB { get; }
}
public class ObjectAConfig : IConfig
{
private class ImmutableConfig : IConfig {
private readonly string valueA;
private readonly int valueB;
public ImmutableConfig(string valueA, int valueB)
{
this.valueA = valueA;
this.valueB = valueB;
}
}
public IConfig Build()
{
return new ImmutableConfig(ValueA, ValueB);
}
... snip: implementation of ObjectAConfig
}
这里是
IConfig
的真正不变的实现,以及您的原始实现。如果需要卡住版本,请调用Build()
。关于c# - 设计一个可变的类,使其在被消耗后变得不可变,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15088773/