Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have fields that are assignable only once?

Tags:

c#

readonly

I need a field that can be assigned to from where ever I want, but it should be possible to assign it only once (so subsequent assignments should be ignored). How can I do this?

like image 638
Afshar Mohebi Avatar asked Oct 20 '09 07:10

Afshar Mohebi


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.

Can we assign value to readonly?

You can assign a value to a ReadOnly variable only in its declaration or in the constructor of a class or structure in which it is defined.

What is readonly property in C#?

In C#, a readonly keyword is a modifier which is used in the following ways: 1. Readonly Fields: In C#, you are allowed to declare a field using readonly modifier. It indicates that the assignment to the fields is only the part of the declaration or in a constructor to the same class.

How do you set a readonly variable?

You cannot change the value or reassign a value to a readonly variable or object in any other method except the constructor.

What is backing field in C#?

A private field that stores the data exposed by a public property is called a backing store or backing field. Fields typically store the data that must be accessible to more than one type method and must be stored for longer than the lifetime of any single method.


1 Answers

That would not be a readonly field then. Your only options for initializing real readonly fields are field initializer and constructor.

You could however implement a kind of readonly functionality using properties. Make your field as properties. Implement a "freeze instance" method that flipped a flag stating that no more updates to the readonly parts are allowed. Have your setters check this flag.

Keep in mind that you're giving up a compile time check for a runtime check. The compiler will tell you if you try to assign a value to a readonly field from anywhere but the declaration/constructor. With the code below you'll get an exception (or you could ignore the update - neither of which are optimal IMO).

EDIT: to avoid repeating the check you can encapsulate the readonly feature in a class.

Revised implementation could look something like this:

class ReadOnlyField<T> {
    public T Value {
        get { return _Value; }
        set { 
            if (Frozen) throw new InvalidOperationException();
            _Value = value;
        }
    }
    private T _Value;

    private bool Frozen;

    public void Freeze() {
        Frozen = true;
    }
}


class Foo {
    public readonly ReadOnlyField<int> FakeReadOnly = new ReadOnlyField<int>();

    // forward to allow freeze of multiple fields
    public void Freeze() {
        FakeReadOnly.Freeze();
    }
}

Then your code can do something like

        var f = new Foo();

        f.FakeReadOnly.Value = 42;

        f.Freeze();

        f.FakeReadOnly.Value = 1337;

The last statement will throw an exception.

like image 135
Brian Rasmussen Avatar answered Sep 30 '22 14:09

Brian Rasmussen