Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression vs nameof

It is a good idea to use nameof over expressions for extracting property names?

//method with expression
protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression, bool isValid, [param: Localizable(true)] string validationError)
{
    string propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
    RaisePropertyChanged(propertyName, isValid, validationError);
}

//the same logic without expression
protected void RaisePropertyChanged(string propertyName, [param: Localizable(true)] string validationError)
{
    RaisePropertyChanged(propertyName, validationError == null, validationError);
}

But the calling is different

public string Url
{
    set
    {
        //with nameof
        RaisePropertyChanged(nameof(Url), this.GetValidationError());
        //with expression
        RaisePropertyChanged(() => Url, this.GetValidationError());
    }
}

What advantages and disadvantages do you know in each approach? Or only execution speed matters ? I mean nameof will be replaced on const value after compilation.

like image 262
isxaker Avatar asked Jul 12 '16 08:07

isxaker


People also ask

What is a Nameof?

A nameof expression produces the name of a variable, type, or member as the string constant: C# Copy. Run.

What is the use of Nameof in C#?

C# NameOf operator is used to get name of a variable, class or method. It returns a simple string as a result. In error prone code, it is useful to capture a method name, in which error occurred. We can use it for logging, validating parameters, checking events etc.

Is Nameof reflection?

Does it use Reflection? nameof is apparently as efficient as declaring a string variable. No reflection or whatsoever!

When was Nameof added to C#?

The nameof operator, added in C# 6.0, addresses this — it allows capturing the string names of symbols that are in the scope. In the example below, ReSharper suggests the replacement of the string literal "order" in the argument of the ArgumentNullException() with the nameof(order) .


2 Answers

Why use expressions to do something you can do on compile time? nameof(Url) is determined on compile time. It costs 0 ms. to evaluate that afterwards. Building an expression is costly and pointless when you can use nameof.

So the bottom line is: don't use expressions unless you really have to (you are already working inside an expression and you have to go from there). Otherwise use nameof.

like image 195
Patrick Hofman Avatar answered Sep 19 '22 11:09

Patrick Hofman


In summary...

...use nameof...

...when you just want the property name.

...or use an expression tree...

...when you need to:

  • ...introspect the selected member.
  • ...get who declares the whole member.
  • ...get the namespace of who declares the whole member.
  • ...and so on.

Since an expression tree is just a data structure unless you compile it into a delegate, it exposes the selected member as a MemberInfo (i.e. MethodInfo, PropertyInfo...) which enables you to do reflection.

Unless you need that, go with nameof.

like image 35
Matías Fidemraizer Avatar answered Sep 22 '22 11:09

Matías Fidemraizer