readonly behavior for structs

S

sadhu

Hi All,

I was surprised to see the readonly behavior differ with respect to
properties and methods.

struct Foo
{
int state;

public int State
{
get { return state; }
set { state = value; }
}

public void SetState(int x)
{
state = x;
}
}

Now if I do something like
class Temp
{
readonly Foo f = new Foo();

public void SomeMethod()
{
f.State = 5; // Doesn't compile, ok
f.SetState(5); // Compiles !!!
}
}

The funny thing is although the method call succeeds, the state
variable in f doesn't change. Using ildasm, I can see that indeed, the
methodcall was made on a copy of f, like
Foo f2 = f;
f2.SetState(5);

One, I personally think that's misleading, it obviously looks like it
is calling the method on f. Two, why doesn't the same thing happen when
the State property was assigned to? After all, assignment to a property
ultimately translates into a set method call. Ideally, the compiler
should report error on both statements.
What do you think?

Regards
Senthil
 
M

Mattias Sjögren

One, I personally think that's misleading, it obviously looks like it
is calling the method on f. Two, why doesn't the same thing happen when
the State property was assigned to? After all, assignment to a property
ultimately translates into a set method call. Ideally, the compiler
should report error on both statements.
What do you think?

Setting a property is almost guaranteed to be modifying the object.
Invoking a regular method is not, and the compiler doesn't know how
SetState will affect the value.



Mattias
 
J

Jon Skeet [C# MVP]

sadhu said:
I was surprised to see the readonly behavior differ with respect to
properties and methods.

<snip>

It surprises me, too. It *is* in the language spec - buried fairly
deeply, admittedly, in the member lookup section. Basically, when
accessing a readonly field outside a constructor (or static constructor
for a static field) the result of the member lookup is the value of the
field, not the field itself.

(Section 14.5.4 of the ECMA spec, parts 8 and 22.)
 
S

sadhu

Thanks for the explanation.

If I understood the spec correctly, 14.5.4.25 says this.f will result
in a value, not a variable. And 14.3.1, paragraph 5 (dealing with
assignment) says that if the instance associated with the property
happens to be a value and not a variable, compile time error occurs. So
the assignment to this.f.State fails to compile.
There is no such restriction for methods, so f.SetState() compiles.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top