Wednesday, December 30, 2009

Reflecting on "invisible" accessors

I was writing a unit test for a utility that writes to a class
property. The utility first checks that the property can be written
to (PropertyInfo.CanWrite == true) and throws an access exception if
not writable. The test was to check for the expected exception.
Theoretically, if the property is read-only, the test should pass
(i.e. property is not writable).

First I tried an automatic property with a private setter:


public string Arg { get; private set; }

FAILED!

Then I tried a standard property with backing var and a private setter:


private string _arg;
public string Arg {
get { return _arg; }
private set { _arg = value; }
}

FAILED

Finally, I removed the setter altogether:


private string _arg;
public string Arg {
get { return _arg; }
}

PASSED

It seems that even though the setter is private, reflection still sees
it and allows writing to it. Rather strange. In my case it's not a
big deal, because I want to be able to write to the property which
I'll be able to do as long as a setter is present. However, it could
result in a strange bug for the utility consumer.