Expressions are short methods by convention. It's all about the delegation of a "thing" to do and what it takes to declare the contract: What you have and what you want in return.
It's pretty good to see in Lambdas: While you'll see this most of the time ...
var tims = users.Where(u => u.Name.StartsWith("Tim"));
... it is perfectly valid to write ...
var tims = users.Where((User u) => u.Name.StartsWith("Tim"));
... and even:
var tims = users.Where((User u) => { return u.Name.StartsWith("Tim"); });
The latter is a full featured delegate syntax with arguments (User u) the curly braces for the method scope and the single-line body. In fact, this is quite the same method as this (except the lack of a method name):
private bool IsTim(User u) { return u.Name.StartsWith("Tim"); }
Which by the way would allow your lambda to look like this because IsTim() has exactly the same signature as the predicate for the Where-clause (= the lambda determining whether a user is a match or not).
var tims = users.Where(IsTim);
Skipping the last example, all of the other three lambda predicates do exactly the same thing but look pretty different:
1 u => u.Name.StartsWith("Tim") 2 (User u) => u.Name.StartsWith("Tim") 3 (User u) => { return u.Name.StartsWith("Tim"); }
Coming from case 3 to case 1 over the last years, the .NET team tried to minimize the keystrokes necessary to achieve the same thing. Delegates 3 have been there forever but with the introduction of Lambdas and Linq, Microsoft needed to simplify the delegating signature which led us to 2 and 1.
While case 2 is basically exact the same thing as case 3, case 1 is only valid in the correct context. It does not define the type of u but infers it in the context it is called. If you call this lambda on a list of users, u will be a user object. If you call it on a list of strings, it's representing a string (and won't compile in this case).
It took a while that Microsoft took over this logic to method and even property bodies but the logic is still the same: Why won't you reduce the necessary keystrokes if you can infer the arguments, return types and methods scopes by it's context?
That's why these two methods are exactly the same:
private bool IsTim(User u) { return u.Name.StartsWith("Tim"); } private bool IsTim(User u) => u.Name.StartsWith("Tim");
u.Name.StartsWith("Tim") will always return a boolean value and the runtime already knows the arrow => to split the method arguments from the method body. It really is "pointing" to the expression producing the return value.
"Pointing to a return value" explains why there should not be a return keyword in public int GetAge() => this.Age;.
returnkeyword? There's nothing else that could be there, just the expression to return, so it's redundant.voidfor a moment - by definition it... consists of a single expression that returns a value whose type matches the method's return type ...AndreturnasThe return statement terminates execution of the method in which it appears and returns control to the calling methodTherefore thereturnkeyword is not used or required as the expression itself satisfies the function of thereturnstatement. See stackoverflow.com/a/19224/426894 for differences between expression and statements.=>instead to help people who golf in C# .. Of course, it's never gonna beat something like 05AB1E which takes "spell this operation differently" to another level ;)returnto be in a context where an expression is expected. You just say you expect it without saying why, so it is hard to answer your "why not" question. What compelling user-focussed benefit do you see as justifying why areturnshould be required? If we can understand what language design principles you have in your head, that gives a good starting point for an answer to the question.