I wonder why it is not possible to do the following:
struct TestStruct
{
public readonly object TestField;
}
TestStruct ts = new TestStruct {
/* TestField = "something" // Impossible */
};
Shouldn't the object initializer be able to set the value of the fields ?
This is not possible. since
readonly
fields cannot be assigned from other thanConstructor
orField Initializer
.What you show is actually
object initializer
. It is just a syntatic sugar, gets comiled into something like thisIs that clear why it doesn't compile?
Because the compiler cannot know for sure that the following code will be executed:
You should initialize readonly members directly inline or inside the constructor.
Object Initializer internally uses a temporary object and then assign each value to the properties. Having a readonly field would break that.
Following
Would translate into
(Here is the answer from Jon Skeet explaining the usage of temporary object with object initalizer but with a different scenario)
From MSDN:
So it's simply not (yet) possible since object initializers are just post-creation assignments.
I ran across an interesting "exception" to this, in the case where the readonly field extends CollectionBase.
Here's the code:
Foo1 is how I initially tried to do it (all these classes came from an external library so we didn't know at first that Bar was readonly). Got the compile error. Then accidentally I retyped it like foo2, and it worked.
After decompiling the dll and seeing that Bar extended CollectionBase, we realized that the second syntax (foo2) was invoking the Add method on the collection. So, in the case of collections, while you can't set a read only property, you can invoke the Add method, via object initializers.
readonly
means that the field can only be set in the constructor (or in a field initializer). Properties specified in the object initializer are set after the constructor has returned. That is,is basically equivalent to
(In a Debug build, the compiler may use a temporary variable, but you get the idea.)