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?
-
If you can assign to it wherever you want, it's hardly 'read-only' is it? What do you actually want? – AakashM Oct 20 '09 at 07:24
-
2That is quite possibly one of the oddest requirements I have seen in a long time. Why would you need a read-only field that is not read-only? – Fredrik Mörk Oct 20 '09 at 07:25
-
I need a read-only field that is assignable only at first time. What I want is very like read-only field in C# currently but I want its first assignment would be possible in somewhere other than constructor. I want to use it for tracking changes of data. – Afshar Mohebi Oct 20 '09 at 07:41
-
@afsharm: I took the liberty of editing your question to describe more what I think that you are actually asking for. I hope I got it right; otherwise, just edit it to your liking. – Fredrik Mörk Oct 20 '09 at 07:49
-
1This may be what you are looking for: http://stackoverflow.com/questions/839788/is-there-a-way-of-setting-a-property-once-only-in-c – Fredrik Mörk Oct 20 '09 at 07:53
-
Sounds like a WriteOnce field. – IDisposable Oct 20 '09 at 07:54
3 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.

- 114,645
- 34
- 221
- 317
-
I'm currently using such a "freeze instance" solution but my class has so many fields and it makes no sense to add 5 line for each field. But what about "field initializer"? I don't know what is it. Is a it possible to assign to read only fields there? Is this as same as "Properties"? – Afshar Mohebi Oct 20 '09 at 07:24
-
No field initializer will not help you here. There are no way you can do what you're asking with a regular readonly field. – Brian Rasmussen Oct 20 '09 at 07:28
-
2@afsharm - If it's not worth adding 5 lines for each field then you obviously don't need this functionality (not really sure why u would anyway). – stevehipwell Oct 20 '09 at 07:34
-
Try the following:
class MyClass{
private int num1;
public int Num1
{
get { return num1; }
}
public MyClass()
{
num1=10;
}
}

- 8,600
- 15
- 47
- 70
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; }

- 1,421
- 2
- 10
- 12
-
No! I don't mean so! Indeed I have an object that is populated by NHibernate from database and then is passed to UI. User may edit some fields or not but I'm supposed to not allows changes in some specific fields. On of the ways that I think I can achieve to this is to define a shadow field for each of fields as READ ONLY and then compare this shadow fields with original ones and realize if changes has been happened. Please consider thoese fields are not populated in constructor. – Afshar Mohebi Oct 20 '09 at 07:32
-
Would it not be better to make it so the user can only edit some of them, making read only fields shown in labels rather than text boxes, or some such? If you are using the property grid you can stick the [ReadOnly] attribute above it. – Oct 20 '09 at 07:46
-
It's SOA application. We have UI in web, winform and console and I'm not allowed to do this anywhere outside of SERVICE. – Afshar Mohebi Oct 20 '09 at 07:49