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

What are the benefits of having a member variable declared as read only? Is it just protecting against someone changing its value during the lifecycle of the class or does using this keyword result in any speed or efficiency improvements?

I don't believe there are any performance gains from using a readonly field. It's simply a check to ensure that once the object is fully constructed, that field cannot be pointed to a new value.
However "readonly" is very different from other types of read-only semantics because it's enforced at runtime by the CLR. The readonly keyword compiles down to .initonly which is verifiable by the CLR.
The real advantage of this keyword is to generate immutable data structures. Immutable data structures by definition cannot be changed once constructed. This makes it very easy to reason about the behavior of a structure at runtime. For instance, there is no danger of passing an immutable structure to another random portion of code. They can't changed it ever so you can program reliably against that structure.
Robert Pickering has written a good blog post about the benefits of immutability. The post can be found here or at the archive.org backup.

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).

There are no apparent performance benefits to using readonly, at least none that I've ever seen mentioned anywhere. It's just for doing exactly as you suggest, for preventing modification once it has been initialised.
So it's beneficial in that it helps you write more robust, more readable code. The real benefit of things like this come when you're working in a team or for maintenance. Declaring something as readonly is akin to putting a contract for that variable's usage in the code. Think of it as adding documentation in the same way as other keywords like internal or private, you're saying "this variable should not be modified after initialisation", and moreover you're enforcing it.
So if you create a class and mark some member variables readonly by design, then you prevent yourself or another team member making a mistake later on when they're expanding upon or modifying your class. In my opinion, that's a benefit worth having (at the small expense of extra language complexity as doofledorfer mentions in the comments).

To put it in very practical terms:
If you use a const in dll A and dll B references that const, the value of that const will be compiled into dll B. If you redeploy dll A with a new value for that const, dll B will still be using the original value.
If you use a readonly in dll A and dll B references that readonly, that readonly will always be looked up at runtime. This means if you redeploy dll A with a new value for that readonly, dll B will use that new value.

There is a potential case where the compiler can make a performance optimization based on the presence of the readonly keyword.
This only applies if the read-only field is also marked as static. In that case, the JIT compiler can assume that this static field will never change. The JIT compiler can take this into account when compiling the methods of the class.
A typical example: your class could have a static read-only IsDebugLoggingEnabled field that is initialized in the constructor (e.g. based on a configuration file). Once the actual methods are JIT-compiled, the compiler may omit whole parts of the code when debug logging is not enabled.
I have not checked if this optimization is actually implemented in the current version of the JIT compiler, so this is just speculation.

Keep in mind that readonly only applies to the value itself, so if you're using a reference type readonly only protects the reference from being change. The state of the instance is not protected by readonly.

Surprisingly, readonly can actually result in slower code, as Jon Skeet found when testing his Noda Time library. In this case, a test that ran in 20 seconds took only 4 seconds after removing readonly.
https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/

Don't forget there is a workaround to get the readonly fields set outside of any constructors using out params.
A little messy but:
private readonly int _someNumber;
private readonly string _someText;
public MyClass(int someNumber) : this(data, null)
{ }
public MyClass(int someNumber, string someText)
{
Initialise(out _someNumber, someNumber, out _someText, someText);
}
private void Initialise(out int _someNumber, int someNumber, out string _someText, string someText)
{
//some logic
}
Further discussion here: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx

Adding a basic aspect to answer this question:
Properties can be expressed as readonly by leaving out the set operator. So in most cases you will not need to add the readonly keyword to properties:
public int Foo { get; } // a readonly property
In contrast to that: Fields need the readonly keyword to achieve a similar effect:
public readonly int Foo; // a readonly field
So, one benefit of marking a field as readonly can be to achieve a similar write protection level as a property without set operator - without having to change the field to a property, if for any reason, that is desired.

Be careful with private readonly arrays. If these are exposed a client as an object (you might do this for COM interop as I did) the client can manipulate array values. Use the Clone() method when returning an array as an object.

Another interesting part of usage of readonly marking can be protecting field from initialization in singleton.
for example in code from csharpindepth:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
readonly plays small role of protecting field Singleton from being initialized twice. Another detail is that for mentioned scenario you can't use const because const forces creation during compile time, but singleton makes creation at run time.

If you have a pre defined or pre calculated value that needs to remain same through out the program then you should use constant but if you have a value that needs to be provided at the runtime but once assigned should remain same throughout the program u should use readonly. for example if you have to assign the program start time or you have to store a user provided value at the object initialization and you have to restrict it from further changes you should use readonly.

readonly can be initialized at declaration or get its value from the constructor only. Unlike const it has to be initialized and declare at the same time.
readonly has everything const has, plus constructor initialization
code https://repl.it/HvRU/1
using System;
class MainClass {
public static void Main (string[] args) {
Console.WriteLine(new Test().c);
Console.WriteLine(new Test("Constructor").c);
Console.WriteLine(new Test().ChangeC()); //Error A readonly field
// `MainClass.Test.c' cannot be assigned to (except in a constructor or a
// variable initializer)
}
public class Test {
public readonly string c = "Hello World";
public Test() {
}
public Test(string val) {
c = val;
}
public string ChangeC() {
c = "Method";
return c ;
}
}
}

There can be a performance benefit in WPF, as it removes the need for expensive DependencyProperties. This can be especially useful with collections

Related

Need some clarification about the static constructor VS static field initializer story in C#

A couple of days ago I asked myself about the difference, if any, between initializing static fields via
the static constructor and doing so by using a static field initializer (inline initialization of a static field at the point of declaration).
After reading plenty of stackoverflow questions on the subject and the famous Jon Skeet's article on the beforefieldinit flag I've now a much better understanding of the difference between the two initialization strategies.
There is one point that I'm not sure about, mostly because I wasn't able to find any official documentation about it.
The static construcutor is guaranteed to be executed only once and I think this holds true even in multi threading scenarios (when different threads create instances of the class and / or use static members of the class. In any case, the static constructor runs once and only once).
Is this true even for the inline initialization of the static fields ? Is the inline initialization of a static field guaranteed to be executed once even in multi threaded scenarios ?
Another point I'm still missing is what are the practical consequences of this difference in the initialization of the static fields of a class. Put another way, I would like to understand when the correctness of a piece of code can be affected by the choice of initializing a static fied inline at the point of declaration (instead of using the static constructor).
Most of the time (this depends mostly on the type of code that I usually work on, namely web applications) I use static readonly fields in service classes to store things that are used by the service I'm writing to perform computations or taking decisions. I decide to put these things inside static fields because they need to be the same for all the possible instances of the class I'm writing, they are actually invariants that don't belong to a particular instance, but instead they belong to the algorithm itself.
This is an example:
public class SomeInterestingService
{
private static readonly int ConstantNumber = 13;
private static readonly string[] Names = new[] { "bob", "alice" };
private readonly INumberGenerator numberGenerator;
public SomeInterestingService(INumberGenerator numberGenerator)
{
this.numberGenerator = numberGenerator ?? throw new ArgumenNullException(nameof(numberGenerator));
}
public int ComputeMagicNumber()
{
int answer = this.numberGenerator.GetNumber();
foreach(var name in names)
{
answer += name.Length;
}
answer += ConstantNumber;
return answer;
}
}
In code like this, is there any practical difference in chosing static constructor initialization or inline initialization of the static fields ConstantNumber and Names, apart from the difference in performance (inline initialization is more performant due to runtime optimizations that are not possible when using the static constructor) ?
Can the correctness of the code above be affected by the coiche in any strange corner case ? (I think not)
Original question:
In code like this, is there any practical difference in chosing static
constructor initialization or inline initialization of the static
fields ConstantNumber and Names, apart from the difference in
performance (inline initialization is more performant due to runtime
optimizations that are not possible when using the static constructor)
?
The answer is no. Either those properties are set upon each construction of the class (instance properties) or set upon the first call to any of the members or methods to the class (static properties).
What #Henk Holterman is saying that because the array of names is a reference type you could theoretically change any of the values in the array. Like:
Names[0] = "Henk Holterman";
Even though the property is readonly. Meaning, you can't assign a new instance of array to that property. The values in the array are not readonly. And could be manipulated if public or by calling a method of that class.

C# Singleton with public 'Instance' field instead of property

Considering the 'standard' C# implementation of a singleton pattern with type initialisation:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public static Singleton Instance
{
get
{
return instance;
}
}
private Singleton() { }
}
Is there any point in the static property? If the static field is marked as readonly, then surely it cannot be written to from anywhere, including from outside the class. For a more terse implementation, would this work?:
public sealed class Singleton
{
public static readonly Singleton Instance = new Singleton();
private Singleton() { }
}
It seems fine to me but I've only ever seen the top one used so I wonder if there is anything wrong that I have missed.
Is there any point in the static property?
Yes. It hides the implementation detail that the value is retrieved from a field in the exact same class. If you expose the field, you're stuck with that implementation forever (assuming you can't later change/rebuild all code referring to it). If you use a property, you could later:
Change to use Lazy<T>
Use a field within a nested class to get potentially lazier initialization if you want to have other static methods in the class
Use some new and funky scheme yet to be devised
Basically, with a property you've got options for future change. With a field, you haven't.
I used not to think this was a relevant difference, but in Noda Time I've had situations where complex type initialization ordering issues have made it really important that I can control this sort of thing. Where I've exposed a public static readonly field in an earlier version, I've later regretted it :(
A public static readonly field works in terms of still being a singleton - it just gives you less control.
As an aside, you may wish to add an empty static constructor to your class. See my articles on singleton implementations and beforefieldinit for more details.
In case of the Singleton pattern it's not very harmful to have a public readonly field rather than just a getter.
The reason the 'standard' implementation is using a getter is to be consistent with the rest of public getters and make you adopt good habits for all the other cases where a getter is more appropriate than a poublic field (for adding functionality without changing the interface for example)
Readonly will mean that it is an instance variable that cant be written to, static is a variable that can be read without instantiating the object. For example you would call them as follows:
//Readonly
var readonlySingleton = new singleton();
var result = readnlySingleton.Instance;
//static readonly
var result = singleton.Instance;

What does immutable and readonly mean in C#?

Is it correct that it is not possible to change the value of an immutable object?
I have two scenarios regarding readonly that I want to understand:
What if I have a collection and mark it as readonly, like the following. Can I still call _items.Add?
private readonly ICollection<MyItem> _items;
And also for the following variable, if later on I call _metadata.Change which will change the internal values of a couple member variable in the Metadata instance. Is _metadata still immutable?
private readonly Metadata _metadata;
For both variables above, I totally understand that I can't directly assign new values to them outside of initializer and constructors.
I suggest you to read the series of blog posts by Eric Lippert. The first part is Immutability in C# Part One: Kinds of Immutability. Very informative and helpful, as always. The series describes what does it mean for a variable to be readonly, immutable etc. in details.
Generally, readonly means only that you can't re-assign a field outside the constructor. The field itself can be modified as long as it stays the same instance. So yes, you can add elements to the collection stored in readonly field.
About mutability, this is more complex and it depends a bit what kind of mutability you consider. When Metadata internal values are references and those references itself (the instances it point to) doesn't change, you could say Metadata stays not mutated. But it is mutated logically. See Eric's posts for more insights.
Marking a field as read-only only means that you cannot change the value of that field. It has no bearing on the internal state of the object there. In your examples, while you would not be able to assign a new metadata object to the _metadata field, nor a new ICollection to the _items field (outside of a constructor that is), you can change the internal values of the existing objects stored in those fields.
An immutable object is one that cannot be changed, once created. In C# strings are immutable. If you look at the string manipulation routines you can see that all of them return a new, modified, string and leaves the original string unchanged.
This facilitates the string handling considerably. When you have a reference to a string, you can be sure that noone else will unexpectedly change it under your feet.
readonly is something else. It means that the reference cannot be changed, once set and that it can only be set during object construction. In your examples you can change the contents of _items or the properties of _metadata, but you cannot assign another ICollection<MyItem> to the _items member or another Metadata instance to _metadata.
readonly is set on the reference to an object. Immutability is a property of the object itself. These can be freely combined. To make sure that a property is not changed in any way, it should be a readonly reference to an immutable object.
There is nothing preventing you from mutating an object stored in a readonly field. So you CAN call _items.Add() and metadata._Change() outside the constructor/initializer. readonly only prevents you from assigning new values to those fields after construction.
private readonly ICollection<MyItem> _items;
Does not prevent items from being added. This simply prevents _items from being re-assigned. The same is true for _metadata. Accessible members of _metadata can be changed - _metadata cannot be re-assigned.
Yes.
Readonly doesn't equal to immutable. You can still call _metadata.Change.
The readonly keyword applies to a variable - this means you can't assign another value to it, but you can alter its internal state. That's why you can alter a collection's items but you can't assign a new collection to the variable.
In languages like C++ there are quite a few different uses of the keyword "const", it is partly easy for developers to pass constant parameters and also constant pointers of constant values.
That is not easy in C#.
We need to build immutable class by definition, which means Once an instance is created, there is no way it can be changed programmatically.
Java has a little easier way than C# because of the keyword final and its usages.
Lets consider this example and see how immutable it is..
public sealed class ImmutableFoo
{
private ImmutableFoo()
{
}
public string SomeValue { get; private set; }
//more properties go here
public sealed class Builder
{
private readonly ImmutableFoo _instanceFoo = new ImmutableFoo();
public Builder SetSomeValue(string someValue)
{
_instanceFoo.SomeValue = someValue;
return this;
}
/// Set more properties go here
///
public ImmutableFoo Build()
{
return _instanceFoo;
}
}
}
You can use it like this
public class Program
{
public static void Main(string[] args)
{
ImmutableFoo foo = new ImmutableFoo.Builder()
.SetSomeValue("Assil is my name")
.Build();
Console.WriteLine(foo.SomeValue);
Console.WriteLine("Hit enter to terminate");
Console.ReadLine();
}
}

Should static properties in a Constants class implement backing fields?

I have a class Constants in which I store a number of static readonly variables.
Should I do this:
private static readonly int _maxThings = 100;
...
public static int MaxThings { get { return _maxThings; } }
That seems kind of redundant to me. Is there any reason why I wouldn't just do the following?
public static int MaxThings { get { return 100; } }
Edit
Okay, so this was a brain fart of a question. I think the point is that if I'm going to be setting this value at initialization then it makes sense to use a static backing field and expose a public get-only property that wouldn't need to be static itself.
If, however, I'm comfortable setting a public static property to a hard value, then there's no functional difference between that and just baking it into the assembly. Unless there's some other concept I'm missing here, in this case I'd just use a const.
Thanks for the answers.
you should do
public const int MaxThings = 100;
there is no reason that i can see to use properties in this case.
Update ->
In response to comments.. If you are developing a library and exporting constants then it's important to understand how constants are consumed int .net. When compiled against your library, the constant values will be inlined and included in the consuming application, such that if your library is updated and consuming application is not then the old constant values will still be present. This is, of course, when static properties should be used.
If you are not developing a library, then the use of const's are fine.
Because constants are well... constant, the value will never change.
The preference for properties are that the signature of a field and a property are different. So changing from a field to a property requires that all callers are recompiled. Thus creating a property in the first instance will avoid that issue if you need to add getter/setter logic at a later date.
Because you have a constant, which will never change, there is no reason at all to implement it as a property. Although you defined a readonly static, as this can only be changed from within the class, externally there is no difference between that and a constant.
From a code readability standpoint I find the second one to be an improvement. Not sure if the compiler is smart enough to optimize in that situation, but the hit is so negligible I would just go with readability.

private constructor gets empty private static readonly string

I have the following code. Is it not the exact code which I am using since it is internal to my place of work, but is a representation of the scenario which I am encountering.
public class Service : ServiceBase
{
private static readonly Service _instance = new Service();
private static readonly string a = #"D:\test.txt";
private Service () : base()
{
// the value stored in "a" is always blank.
Console.Writeline(a);
}
static void Main(string[] args)
{
Run(_instance);
}
}
This code is a windows service (there is service specific code in the base class). For some reason the value stored in "a" is always blank in the constructor. Is there something obvious which is doing this, or is it a quirk in the .NET platform?
Swap round the declarations of the _instance and a fields. In C#, static fields are initialized in the order in which they're declared. In other words, your Server constructor is running too early.
Or you could declare a as const, which removes it from the construction process.
The problem is that you're calling the constructor before the initializer for a is run, so you're seeing the default value for a. In fact, it's not blank (an empty string) - it's null. You can fix this by reordering:
public class Service : ServiceBase
{
// Initialize a first
private static readonly string a = #"D:\test.txt";
private static readonly Service _instance = new Service();
...
}
The static initializers are run in the textual order (which becomes somewhat undefined with partial classes). From section 10.5.5.1 of the C# 3.0 spec:
The static field variable initializers
of a class correspond to a sequence of
assignments that are executed in the
textual order in which they appear in
the class declaration. If a static
constructor (ยง10.12) exists in the
class, execution of the static field
initializers occurs immediately prior
to executing that static constructor.
Otherwise, the static field
initializers are executed at an
implementation-dependent time prior to
the first use of a static field of
that class.
I'm not sure I use that would though... it's too easy to break.
Can you change it to const? That would be more robust:
private const string a = #"D:\test.txt";
That way it won't matter if someone changes the order again at a later date, thinking that reordering is a harmless operation. Presumably you were unaware of the importance of the order here, otherwise you wouldn't have asked this question - how willing are you to gamble that another programmer looking at the same code won't have the same issue? :)
Static fields are instantiated in the order they appear in the text file. So your Service is being constructed before the string is initialized. if you swap those two lines it should work.
Link: http://msdn.microsoft.com/en-us/library/aa645758%28VS.71%29.aspx
Oh, and the singleton pattern is often an anti-pattern. Try to avoid using it if possible.

Categories

Resources