Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a read only property

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 would appreciate any comments/advice/etc.

like image 947
akonsu Avatar asked Oct 12 '10 18:10

akonsu


People also ask

How is read only property implemented C#?

In c#, you can initialize the readonly fields either at the declaration or in a constructor. The readonly field values will evaluate during the run time in c#. Once values assign to the read-only fields, those values must be the same throughout the application.

How can you make a property write only?

You can use WriteOnly only at module level. This means the declaration context for a WriteOnly property must be a class, structure, or module, and cannot be a source file, namespace, or procedure. You can declare a property as WriteOnly , but not a variable.

What is readonly property?

A class property declared read-only is only allowed to be initialized once, and further changes to the property is not allowed. Read-only class properties are declared with the readonly keyword* in a typed property.

What is read only and write only properties C#?

Read-Only Properties: When property contains only get method. Write Only Properties: When property contains only set method. Auto Implemented Properties: When there is no additional logic in the property accessors and it introduce in C# 3.0.


2 Answers

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.

like image 160
Oded Avatar answered Sep 21 '22 07:09

Oded


C# 6.0 adds readonly auto properties

public object MyProperty { get; } 

So when you don't need to support older compilers you can have a truly readonly property with code that's just as concise as a readonly field.


Versioning:
I think it doesn't make much difference if you are only interested in source compatibility.
Using a property 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.

Convention:
You are following the convention. 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 actually immutable (barring reflection). Whereas in case of a property you can only see that you cannot change it, so you'd 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.

like image 40
CodesInChaos Avatar answered Sep 19 '22 07:09

CodesInChaos