Marking TextReader readonly

Viewed 54

Given:

class Parser {
  public Parser(TextReader source) => Source = source;
  public int GetChar() => Source.Read();
  private readonly TextReader Source = null;
}

How can TextReader be marked readonly? I mean, you are reading from a buffer and things are changing. What am I missing?

Originally, I had Source without the readonly but it was suggested by a code helper and it does compile.

Thanks

2 Answers

readonly does not mean that the text reader object itself is read-only and/or immutable.

In your particular example it means that, after the constructor has finished executing, the field Source will never point to another TextReader than the one assigned in the constructor. Trying to assign a different value to Source outside the constructor will yield a compile-time error.

This can be a valuable invariant: In particular, it means that if you add a null check in your constructor, your instance methods can rely on Source never being null.

Here is the relevant part from the C# language reference:

In a field declaration, readonly indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class. A readonly field can be assigned and reassigned multiple times within the field declaration and constructor.

A readonly field can't be assigned after the constructor exits. [...]

The thing to understand here is the Source member variable in the class is a separate thing from the object itself. The variable holds a reference to the object. When you mark the variable readonly, you're marking the reference as readonly, not the object.

This means you can use the reference to still call methods and change properties on the actual object. But it's still valuable because, once that reference is set by the constructor, it stays set. You know know the object on the other end of this reference is the same object throughout the life of the class.

This is helpful, for example, to know a member in a class will never be null. Also think about something like opening, eg, a file stream, network connection, or database connection, where changing out the object might lose that important state on the other end of the connection.

Related