简体   繁体   中英

Difference between Expression-Bodied Properties and simple Getter Properties

After reading some source code of different c# project i noticed different ways of writing (almost) the same statement regarding public "getter" and private "setter" properties.

First way with only properties:

public int x { get; private set; }

Second way with expression-bodied properties:

private int _x;
public int x => _x;

I know that public int x { get; } public int x { get; } is equivalent to

private readonly int __x;
public int x { get { return __x } }

So I understand the difference between expression-bodied and normal properties in the case of a single "getter". What i do not understand is the difference when there is a private field that holds the referenced value. I thought that maybe the second one is faster because you have access to the field directly instead of a method call inside your class. Is it just a stylistic difference or is one of the examples faster, more robust, etc?

You have two groups of constructs which are equivalent.

Group 1

When you don't need write access to the backing field outside the constructor, you can use any of these constructs:

private readonly int _x;
public int x => _x;

or

private readonly int _x;
public int x { get => _x; }

or

private readonly int _x;
public int x { get { return _x; } }

or

public int x { get; }

Group 2

When you need access to the backing field outside the constructor, you can use any of these constructs:

private int _x;
public int x => _x;

or

private int _x;
public int x { get => _x; }

or

private int _x;
public int x { get { return _x; } }

or

public int x { get; private set; }

You can expect all of the alternatives to be equally fast. In the last construct the compiler will inject a setter method (it will inject a backer field too, as for every automatic property). In the other cases you access the field directly. The injected setter will almost certainly be inlined by the jitter, which removes the performance penalty of a method call. Check this Q&A for details on JIT inlining.

The automatic property is certainly more concise, which makes your code neater, especially when you have many properties. But at the end of the day it comes down to personal preference (or your team's coding rules).

If you use a private backing field, You are encapsulating the information and creating more robust code. It also improves the readability in some cases.
There is also the fact that the value is stored safely in a field and so if you have logic within your getters and setters that needs to change in the future it is separated from the actual value store and makes changing that implementation easier in future

Note that there's even another possibility if you initialize the property in the constructor

public int X { get; }

This is a getter-only property introduced in C# 6.0. You can assign it in the constructor (and then never again)

public MyClass (int x) // Constructor
{
    X = x;
}

or with an initializer

public int X { get; } = 100;

You should not care about speed for those things. Create an easy to read and robust code. The C# compiler or the Jitter (Just In Time compiler running when the application starts, and methods are called for the first time) will possibly inline the code and not even call the getter or the setter.

The difference between normal and expression-bodied properties, methods and constructors is only of syntactical nature. There is no difference in behavior. Both variants produce the same compiled IL code and therefore, there is no difference in speed.

public int X => _x; is simply a shorter syntax for public int X { get { return _x; } } public int X { get { return _x; } } . This is also called syntactic sugar .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM