tags:

views:

129

answers:

5

hello,

i am pretty sure this has been asked. although i have not found a discussion about this on stackoverflow. please redirect me if there is a duplicate to this one.

i need to implement a read only property on my type. moreover the value of this property is going to be set in the constructor and it is not going to be changed (i am writing a class that exposes custom routed UI commands for WPF but it does not matter).

i see two ways to do it:

1.

class MyClass
{
    public readonly object MyProperty = new object();
}

2.

class MyClass
{
    private readonly object my_property = new object();
    public object MyProperty { get { return my_property; } }
}

with all these FxCop errors saying that i should not have public member variables, it seems that the second one is the right way to do it. correct?

is there any difference between a get only property and a read only member in this case?

i wold appreciate any comments/advice/etc.

konstantin

+8  A: 

The second way is the preferred option.

private readonly int MyVal = 5;

public int MyProp { get { return MyVal;}  }

This will ensure that MyVal can only be assigned at initialization (it can also be set in a constructor).

As you had noted - this way you are not exposing an internal member, allowing you to change the internal implementation in the future.

Oded
thanks. the first option also ensures the same. what do you think is the reason why this one is the preferred option?
akonsu
Is there any reason we shouldn't use `public int MyProp { get; private set; }`? I know it's not truly readonly, but it's pretty darned close.
Mike Hofer
@Mike Hofer - Since the int is declared as _readonly_, you can't change it outside of a constructor.
Oded
@Oded: True, but he's asking how to implement a readonly property, not a readonly field. I've always understood that the proper implementation of a readonly property was the one I've shown, but I'm *always* willing to learn something new. I will admit that the implementation I've provided is only readonly from the perspective of code outside the implementing class, so (in that regard) it's only quasi-readonly. Is that, perhaps, why the implementation you've shown is the preferred implementation? And if so, doesn't that kind of render much of the utility of autoproperties moot?
Mike Hofer
@Mike Hofer - it really depends on what the intention is... The version I wrote exposes an internal member whose value cannot change after initialization. Yours exposes a member whose value may change after initialization. Really depends on what you want... Mine is readonly, as in, can't be changed at all after init, yours is readonly, as in, by any external class.
Oded
@Oded - I can accept that. It's a subtle, but important difference. I can see where it would be useful if you wanted to expose a property that behaved as a constant both internally and externally. Mine certainly wouldn't do that.
Mike Hofer
+2  A: 

The second method is preferred because of the encapsulation. You can certainly have the readonly field be public, but that goes against C# idioms in which you have data access occur through properties and not fields.

The reasoning behind this is that the property defines a public interface and if the backing implementation to that property changes, you don't end up breaking the rest of the code because the implementation is hidden behind an interface.

Joshua Rodgers
+1  A: 

I agree that the second way is preferable. The only real reason for that preference is the general preference that .NET classes not have public fields. However, if that field is readonly, I can't see how there would be any real objections other than a lack of consistency with other properties. The real difference between a readonly field and get-only property is that the readonly field provides a guarantee that its value will not change over the life of the object and a get-only property does not.

Eric Mickelsen
this is a good explanation. thanks.
akonsu
+1  A: 

You can do this:

public int Property { get { ... } private set { ... } }
rmx
+2  A: 

Versioning:
I think it doesn't make much difference if you are only interested in source compatibility. But the second one is better for binary compatibility since you can replace it by a property which has a setter without breaking compiled code depending on your library.

Convertion:
You are following the convertion. In cases like this where the differences between the two possibilities are relatively minor following the convention is better. One case where it might come back to bite you is reflection based code. It might only accept properties and not fields, for example a property editor/viewer.

Serialization
Changing from field to property will probably break a lot of serializers. And AFAIK XmlSerializer does only serialize public properties and not public fields.

Using an Autoproperty
Another common Variation is using an autoproperty with a private setter. While this is short and a property it doesn't enforce the readonlyness. So I prefer the other ones.

Readonly field is selfdocumenting
There is one advantage of the field though:
It makes it clear at a glance at the public interface that it's readonly, whereas in case of a property you have to refer to the documentation or implementation.

But to be honest I use the first one quite often in application code since I'm lazy. In libraries I'm typically more thorough and follow the convention.

CodeInChaos