Tuesday, November 15, 2005

C# Public Readonly Fields

C# public readonly fields are great. Why waste your time writing this:
public string foo;
public string Foo
get { return foo; }
When this:
public readonly string Foo;
gives you the same level of protection?

I know people simply hate public fields. The problem is this hatred has become blind hatred. A public field is dismissed without thought. In reality a private field and a getter gains me little over a public readonly field. You could argue that making a field readonly ensures it contains the value expected and is better than simply a private field with a getter.

Because I actively seek Good Citizens and Constructor Injection the field being writable only in a constructor or on the same line as the declaration is rarely a problem.

I prefer less code over blindly following a rule that simply doesn't apply to readonly fields.


  1. Maxx Daymon2:29 AM

    The problem is that it really is not the same level of encapsulation as a property, and for all the classic reasons. Versioning of the class over time demonstrates this:

    When you release version 1.0.1 of your class to add a security check and it now looks like this:

    public string Foo {
    get {
    return foo;

    Existing clients will break since you have changed to a call to get_Foo() rather than direct access to a Class.Foo field.

    C# hides the fact that you are actually encapsulating the access to the member through a function call. A readonly field is not equivalent.

    If you aren't a shared component, and you always rebuild and redeploy everything, this is not so much an issue, but only due to the syntactic sugar of properties. If this class is used by a managed language without property support (e.g,. MC++ calling get_Foo()), then it becomes the classic maintenance issue.

  2. This isn't really encapsulation - you're still exposing internal state (fair enough, it can't be modified, but it's still not encapsulation). It isn't even information hiding, which is people traditionally confuse with encapsulation (e.g. "Look, I've got a get/set pair - I'm using encapsulation!").

  3. I wasn't actually stating that this is the same as encapsulation, but rather that it provided the same level of protection as encapsulation (or, more correctly, information hiding). I updated the entry to clarify this.

  4. Maxx, I responded to your comment when I woke this morning, still a bit asleep. After rereading, I see your point now. It's a good point and I completely agree with it.

    Luckily for me, the majority of the projects I find myself on are working strictly with C# and the get_Foo() methed is never called directly.

  5. The real difference though is that while you can push a readonly property into an interface, you cannot push a readonly field into an interface.


Note: Only a member of this blog may post a comment.