Mike Mike - 2 months ago 11x
C# Question

What is the => assignment in C# in a property signature

I came across some code that said

public int MaxHealth => Memory[Address].IsValid ? Memory[Address].Read<int>(Offs.Life.MaxHp) : 0;

Now I am somewhat familiar with Lambda expressions. I just have not seen it used it this way.

What would be the difference between the above statement and

public int MaxHealth = x ? y:z;


What you're looking at is an expression-bodied member, not a lambda expression.

When the compiler encounters an expression-bodied property member, it will essentially convert it into a getter, like this:

public int MaxHealth
        return Memory[Address].IsValid ? Memory[Address].Read<int>(Offs.Life.MaxHp) : 0;

(You can verify this for yourself by pumping the code into a tool called TryRoslyn.)

Expression-bodied members - like most C# 6 features - are just syntactic sugar. This means that they don’t provide functionality that couldn't otherwise be achieved through existing features. Instead, these new features allow a more expressive and succinct syntax to be used

As you can see, expression-bodied members have a handful of shortcuts that make property members more compact:

  • There is no need to use a return statement because the compiler can infer that you want to return the result of the expression
  • There is no need to create a statement block because the body is only one expression
  • There is no need to use the get keyword because it is implied by the use of the expression-bodied member syntax.

I have made the final point bold because it is relevant to your actual question, which I will answer now.

The difference between...

// expression-bodied member property
public int MaxHealth => x ? y:z;


// field with field initializer
public int MaxHealth = x ? y:z;

Is the same as the difference between...

public int MaxHealth
        return x ? y:z;


public int MaxHealth = x ? y:z;

Which - if you understand properties - should be obvious.

Just to be clear, though: the first listing is a property with a getter under the hood that will be called each time you access it. The second listing is is a field with a field initializer, whose expression is only evaluated once, when the type is instantiated.

This difference in syntax is actually quite subtle and can lead to a "gotcha" which is described by Bill Wagner in a post entitled "A C# 6 gotcha: Initialization vs. Expression Bodied Members".

While expression-bodied members are lambda expression-like, they are not lambda expressions. The fundamental difference is that a lambda expression results in either a delegate instance or an expression tree. Expression-bodied members are just a directive to the compiler to generate a property behind the scenes. The similarity (more or less) starts and end with the arrow (=>).

I'll also add that expression-bodied members are not limited to property members. They work on all these members:

  • Properties
  • Indexers
  • Methods
  • Operators

However, they do not work on these members:

  • Constructors
  • Deconstructors
  • Nested Types
  • Events
  • Fields