How to implement a read-only property

I need to implement a read-only property in my type. In addition, the value of this property will be set in the constructor, and it will not be changed (I am writing a class that provides user routed interface commands for WPF, but it does not matter).

I see two ways to do this:

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

With all these FxCop errors saying that I don't have public member variables, it seems that the second is the right way to do this. Right?

Is there a difference between a get only property and a read-only member?

I would appreciate any comments / advice, etc.

+69
c # properties readonly
Oct 12 '10 at 18:29
source share
7 answers

Versioning:
I think this does not really matter if you are only interested in source compatibility.
Using a property is better for binary compatibility, since you can replace it with a property that has a setter without breaking the compiled code depending on your library.

Convention:
You follow the convention. In such cases, when the differences between the two possibilities are relatively insignificant in accordance with the agreement, it is better. One case where he may return to bite you is a reflection-based code. It can only accept properties, not fields, such as a property editor / viewer.

Serialization
The transition from field to ownership is likely to lead to the breakdown of many serializers. And AFAIK XmlSerializer serializes public properties, not public fields.

Using Autoproperty
Another common variation is the use of an autoprocessor using a private setter. Although this is short, the property does not provide read consistency. Therefore, I prefer others.

Readonly field is self-documenting
There is one advantage of the field:
This makes it clear at a glance at the public interface that it is virtually immutable (ban on reflection). If in the case of a property you can only see that you cannot change it, you will have to refer to the documentation or implementation.

But to be honest, I use the first one quite often in the application code, since I'm lazy. In libraries, I tend to be more careful and stick to the agreement.

C # 6.0 adds readonly automatic properties

 public object MyProperty { get; } 

Therefore, when you do not need to support older compilers, you can really have a readonly property with code that is as concise as the readonly field.

+47
Oct 12 2018-10-10
source share

The second method is the preferred option.

 private readonly int MyVal = 5; public int MyProp { get { return MyVal;} } 

This ensures that MyVal can only be assigned during initialization (it can also be set in the constructor).

As you have already noted, this way you do not expose the internal member, which allows you to change the internal implementation in the future.

+58
12 Oct '10 at 18:29
source share

With the introduction of C # 6 (in VS 2015), now you can have get - only automatic properties in which the implicit support field is readonly (i.e. values ​​can be assigned in the constructor, but not elsewhere)

 public string Name { get; } public Customer(string name) // Constructor { Name = name; } private void SomeFunction() { Name = "Something Else"; // Compile-time error } 

Now you can also initialize properties (with or without a setter) inline:

 public string Name { get; } = "Boris"; 

Returning to the question, this gives you the advantages of option 2 (an open member is a property, not a field) with a multiplicity of option 1.

Unfortunately, it does not guarantee a guarantee of invariability at the open interface level (as in @CodesInChaos indicates self-documentation), because for a consumer of a class that does not have a setter, it is indistinguishable from having a private setter.

+40
May 7 '15 at 3:15
source share

You can do it:

 public int Property { get { ... } private set { ... } } 
+11
Oct 12 2018-10-18
source share

I agree that the second option is preferable. The only real reason for this preference is the general preference that .NET classes do not have public fields. However, if this field is read-only, I don’t see how any real objections will exist, except for the lack of consistency with other properties. The real difference between the readonly field and the get-only field is that the readonly field ensures that its value does not change throughout the lifetime of the object, and that the get-only property does not.

+5
Oct 12 2018-10-12
source share

The second method is preferred due to encapsulation. Of course, the readonly field may be publicly available, but this contradicts C # idioms in which you have access to data through properties, not fields.

The rationale for this is that the property defines an open interface, and if the implementation of support for this property changes, you do not violate the rest of the code, because the implementation is hidden behind the interface.

+4
Oct 12 2018-10-12
source share

another way (my favorite) starting with C # 6

 private readonly int MyVal = 5; public int MyProp => MyVal; 

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties#expression-body-definitions

0
Jul 17 '19 at 15:26
source share



All Articles