Difference in C# between different getter styles

10.3k views Asked by At

I do sometimes see abbreviations in properties for the getter. E.g. those two types:

public int Number { get; } = 0

public int Number => 0;

Can someone please tell me if there are any differences between those two. How do they behave? Are both of them read-only?

3

There are 3 answers

1
Jon Skeet On BEST ANSWER

Yes, both of them are read-only, but there is a difference. In the first one, there's a backing field which is initialized to 0 before the constructor is executed. You can change the value only in the constructor, just like a regular read-only field. The getter itself just returns the value of the field.

In the second one, the getter just returns 0 every time, with no field involved.

So to avoid using any automatically implemented properties or expression-bodied members at all, we have:

First version

private readonly int _number = 0;
public int Number { get { return _number; } }

Second version

public int Number { get { return 0; } }

A clearer example of the difference might be seen like this:

public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime CurrentTime => DateTime.UtcNow;

If you create a single object, its CreationTime property will always give the same result - because it's stored in a readonly field, initialized on object construction. However, every time you access the CurrentTime property, that will cause DateTime.UtcNow to be evaluated, so you'll get a potentially different result.

3
Jehof On

These are C# 6 language features.

First example

public int Number { get; } = 0

The first example is a getter-only auto property. The backing field of a getter-only auto-property is implicitly declared as readonly.

Second example

public int Number => 0;

And the second example is expression bodies on property-like function members. Note that there isn't any get keyword: It is implied by the use of the expression body syntax.

Both are readonly.

3
Hans Kesting On

One difference is when that 0 is evaluated: at object creation or when the property is used.

You can see this better with DateTime properties:

class SomeTestClass
{
    public DateTime Start { get; } = DateTime.Now;

    public DateTime Now => DateTime.Now;
}

The Start property keeps returning the same time (of when the instance was created), while Now changes to reflect the current time.

Explanation:

The first version ("Start") supplies an initial value that may even be overwritten by the constructor. So this is evaluated just once.
The second version ("Now") provides the expression that will be the "getter" of this property. So this is evaluated every time the property is read. There isn't even a backing field that the constructor can overwrite.