James James - 3 months ago 11
C# Question

Can this immutable property be converted to an auto property?

I've been going through an app I'm developing and it makes heavy use of immutability. I've just discovered getter-only automatic properties are in C# 6.0 so I'm refactoring to use those. I've hit one possible question-mark though, which is where I'm exposing

private IList<T>
objects as
ReadOnlyCollection<T>
through public properties, to avoid the possibility of them being casted back to their original
List<T>
object, e.g.

private IList<string> tags = new List<string>();


public IEnumerable<string> Tags => new ReadOnlyCollection<string>(this.tags);


Is there any way to use auto-properties with this type of customised getter?

Answer

Unfortunately, no. Auto-properties are a shortcut for properties which don't have customized getters or setters.


As a side note: As Sinatr correctly mentions in the comments, you are creating a new instance of the ReadOnlyCollection on every property invocation. That is untypical for a property. Consider returning the same instance every time instead:

private IList<string> tags = new List<string>();
public IEnumerable<string> Tags { get; }

public MyClass()
{
    Tags = new ReadOnlyCollection<string>(this.tags);
}

This works because ReadOnlyCollection reflects changes made to the underlying collection:

An instance of the ReadOnlyCollection<T> generic class is always read-only. A collection that is read-only is simply a collection with a wrapper that prevents modifying the collection; therefore, if changes are made to the underlying collection, the read-only collection reflects those changes.


Note: The constructor is required: C# does not allow field initializers to reference other instance fields, since the compiler might rearrange the initialization order. In VB.NET, where fields are initialized in the order in which they appear, this could be written as follows:

Private tagList As New List(Of String)()
Public ReadOnly Property Tags As IEnumerable(Of String) = New ReadOnlyCollection(Of String)(tagList)