Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You can roll your own (see the end of the answer for a more robust implementation that is thread safe and supports default values).</p> <pre><code>public class SetOnce&lt;T&gt; { private bool set; private T value; public T Value { get { return value; } set { if (set) throw new AlreadySetException(value); set = true; this.value = value; } } public static implicit operator T(SetOnce&lt;T&gt; toConvert) { return toConvert.value; } } </code></pre> <p>You can use it like so:</p> <pre><code>public class Foo { private readonly SetOnce&lt;int&gt; toBeSetOnce = new SetOnce&lt;int&gt;(); public int ToBeSetOnce { get { return toBeSetOnce; } set { toBeSetOnce.Value = value; } } } </code></pre> <p><strong>More robust implementation below</strong></p> <pre><code>public class SetOnce&lt;T&gt; { private readonly object syncLock = new object(); private readonly bool throwIfNotSet; private readonly string valueName; private bool set; private T value; public SetOnce(string valueName) { this.valueName = valueName; throwIfGet = true; } public SetOnce(string valueName, T defaultValue) { this.valueName = valueName; value = defaultValue; } public T Value { get { lock (syncLock) { if (!set &amp;&amp; throwIfNotSet) throw new ValueNotSetException(valueName); return value; } } set { lock (syncLock) { if (set) throw new AlreadySetException(valueName, value); set = true; this.value = value; } } } public static implicit operator T(SetOnce&lt;T&gt; toConvert) { return toConvert.value; } } public class NamedValueException : InvalidOperationException { private readonly string valueName; public NamedValueException(string valueName, string messageFormat) : base(string.Format(messageFormat, valueName)) { this.valueName = valueName; } public string ValueName { get { return valueName; } } } public class AlreadySetException : NamedValueException { private const string MESSAGE = "The value \"{0}\" has already been set."; public AlreadySetException(string valueName) : base(valueName, MESSAGE) { } } public class ValueNotSetException : NamedValueException { private const string MESSAGE = "The value \"{0}\" has not yet been set."; public ValueNotSetException(string valueName) : base(valueName, MESSAGE) { } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload