Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way of setting a property once only in C#

Tags:

c#

.net

I'm looking for a way to allow a property in a C# object to be set once only. It's easy to write the code to do this, but I would rather use a standard mechanism if one exists.

 public OneShot<int> SetOnceProperty { get; set; } 

What I want to happen is that the property can be set if it is not already set, but throw an exception if it has been set before. It should function like a Nullable value where I can check to see if it has been set or not.

like image 402
Nick Randell Avatar asked May 08 '09 13:05

Nick Randell


People also ask

How do you set a variable only once in C#?

To do this, first you have to make a bool variable that tells you if the variable has been set: bool isSet; Then, we make the variable be true when the variable you want to be able to be set only once is set. Note that this returns null if this variable is accessed before it is set.

What are INIT only setters?

init (C# Reference) An init-only setter assigns a value to the property or the indexer element only during object construction. This enforces immutability, so that once the object is initialized, it can't be changed again. For more information and examples, see Properties, Auto-Implemented Properties, and Indexers.

What is readonly property in C#?

In a field declaration, readonly indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class. A readonly field can be assigned and reassigned multiple times within the field declaration and constructor.

What does init do?

The git init command creates a new Git repository. It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository.


1 Answers

There is direct support for this in the TPL in .NET 4.0;

(edit: the above sentence was written in anticipation of System.Threading.WriteOnce<T> which existed in the "preview" bits available at the time, but this seems to have evaporated before the TPL hit RTM/GA)

until then just do the check yourself... it isn't many lines, from what I recall...

something like:

public sealed class WriteOnce<T> {     private T value;     private bool hasValue;     public override string ToString()     {         return hasValue ? Convert.ToString(value) : "";     }     public T Value     {         get         {             if (!hasValue) throw new InvalidOperationException("Value not set");             return value;         }         set         {             if (hasValue) throw new InvalidOperationException("Value already set");             this.value = value;             this.hasValue = true;         }     }     public T ValueOrDefault { get { return value; } }      public static implicit operator T(WriteOnce<T> value) { return value.Value; } } 

Then use, for example:

readonly WriteOnce<string> name = new WriteOnce<string>(); public WriteOnce<string> Name { get { return name; } } 
like image 177
Marc Gravell Avatar answered Oct 14 '22 08:10

Marc Gravell