What Are the Benefits to Marking a Field as 'Readonly' in C#

What are the benefits to marking a field as `readonly` in C#?

The readonly keyword is used to declare a member variable a constant, but allows the value to be calculated at runtime. This differs from a constant declared with the const modifier, which must have its value set at compile time. Using readonly you can set the value of the field either in the declaration, or in the constructor of the object that the field is a member of.

Also use it if you don't want to have to recompile external DLLs that reference the constant (since it gets replaced at compile time).

Is there any benefit to making a C# field read-only if its appropriate?

The benefit is purely semantic. It will help users of your code explicitly understand that this field can't be changed after object is created. Compiler will prevent unwanted changes of this field. I totally agree with following quote from Python Zen:

Explicit is better than implicit.

Some details:

The only difference between normal field and read-only field is flag initonly in IL. There is no optimization about it (as with constants) because actually it allows all operations (get and set, but only in ctor). It is just hint to compiler: don't let it be changed after construction.

.field public initonly int32 R

Is there any point to marking a private field readonly?

It's always nice to have the compiler prevent you from being dumb.

It's especially nice to have the compiler prevent other people from being dumb, even if they're not familiar with the codebase.

It also serves to tell other people reading your code that the field will never change

why can I set the value of a field in a readonly variable? c#

You can change HasBorder.Value but you can’t change HasBorder because HasBorder is readonly. Try equating HasBorder to something else and it will fail.

It’s important to keep in mind that when a readonly data member is of a reference type (i.e. instance of a class and not either a struct or a base data type) the reference is constant, but the instance it points to is not. So the internal status of a readonly instance can change and can be changed

Why is this field declared as private and also readonly?

If it's private and readonly, the benefit is that you can't inadvertently change it from another part of that class after it is initialized. The readonly modifier ensures the field can only be given a value during its initialization or in its class constructor.

If something functionally should not change after initialization, it's always good practice to use available language constructs to enforce that.

On a related note, C# 9 introduces the init accessor method for properties, which indicates the property value can only be set during object construction, e.g.:

class InitExample
{
private double _seconds;

public double Seconds
{
get { return _seconds; }
init { _seconds = value; }
}
}

Why would I choose a private read-only auto-property over a read-only field?

I replace the full context. This sentence is in the chapter Primary Contructors. With primary constructors, it make sense to replace read-only backing field by Auto-Property Initializers.

I agree, this sentence is weird :

Now, whenever a read-only field is declared, you can declare a read-only auto-property possibly as private, if that level of encapsulation is required.

When I read this, I see two axioms :

  1. With primary constructor, you should use auto-property initializer instead of read-only backing field.
  2. Hey guy, it's possibly to declare the property with auto initializer private

I think the author has favored brevity instead of readability or the author advocate to the end of field.

But the primary constructor isn't integrated in the final C#6 or next versions, so we still need backing field a long time.

Is a readonly field in C# thread safe?

Yes - your code doesn't expose this within either constructor, so no other code can "see" the object before it's been fully constructed. The .NET memory model (as of .NET 2) includes a write barrier at the end of every constructor (IIRC - search Joe Duffy's blog posts for more details) so there's no risk of another thread seeing a "stale" value, as far as I'm aware.

I'd personally still usually use a property instead, as a way of separating implementation from API, but from a thread-safety point of view it's fine.



Related Topics



Leave a reply



Submit