Create a mutable class, which after its consumption becomes immutable

Assume that the script does not allow you to implement an immutable type. Following this assumption, I would like opinions / examples on how to properly design a type that, after its consumption, become unchanged.

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;
    }
  }
}

When ObjectAconsumes ObjectAConfig:

public ObjectA {

  public ObjectA(ObjectAConfig config) {

    _config = config;
    _config.Consumed = true;
  }
}

I'm not sure if this just works, I would like to know if there is a better pattern (excluded, as said, making it ObjectAConfigunchanged in design from the very beginning).

For instance:

  • can determine the meaning of a monad like Once<T>, which allows you to initialize a wrapped value only once?

  • Can it make sense to determine the type that returns the type itself, which changes the personal field?

+5
1

, , " ", . - .

, - :

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); }
}

: . , :

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().

+10

All Articles