Afshar
Afshar

Reputation: 11483

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

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?

Upvotes: 6

Views: 3127

Answers (3)

Himadri
Himadri

Reputation: 8876

Try the following:

class MyClass{
private int num1;

public int Num1
{
   get { return num1; }

}


public MyClass()
{
num1=10;
}

}

Upvotes: 1

Brian Rasmussen
Brian Rasmussen

Reputation: 116401

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.

Upvotes: 17

Eric Minkes
Eric Minkes

Reputation: 1431

Or maybe you mean a field that everyone can read but only the class itself can write to? In that case, use a private field with a public getter and a private setter.

private TYPE field;

public TYPE Field
{
   get { return field; }
   private set { field = value; }
}

or use an automatic property:

public TYPE Field { get; private set; }

Upvotes: 0

Related Questions