Introduction
A common practice is to use lambda expressions instead of string
constants - "magic strings" - as the names of the properties in the INotifyChanged
paradigm: something like NotifyPropertyChanged(()=>Property);
instead of NotifyPropertyChanged("Property");
We will show that this reduces the speed of Binding execution. Also, we will show a trivial way to work around this.
Property Name Infer From Expression
Generally such construction requires a property name infer from the expression:
public static string NameInfer<T>( Expression<Func<T>> itemExpression )
{
switch ( itemExpression.Body.NodeType )
{
case ExpressionType.Constant:
default:
return ( ( itemExpression.Body as ConstantExpression ).Value as String );
case ExpressionType.MemberAccess:
return ( ( itemExpression.Body as MemberExpression ).Member.Name );
}
}
This calculation takes a certain time. Below - the results of time testing. An average of twenty thousand fold sendings of a text ("Lorem ipsum...") to property is calculated. Left side column - result for string
constant property name; middle column - result for expression derived property name:
Numerical values above may seem ridiculous, but with intensive communication between View
and ViewModel
can be significant; timing difference also becomes important in the case of ViewModel
- ViewModel
communications.
Repair
Fortunately repair is straightforward and somewhat dull. It is enough to declare readonly string
variables and evaluate them once in a ViewModel
's constructor using expression to string
conversion, and to use these variables instead of constant property names in all further calls to NotifyPropertyChanged
- something like in the code snippet below:
...
private readonly string sr_view1Text2;
...
#region ctor
public View1Model()
{
...
sr_view1Text2 = NameTypeHelper.NameInfer( ( ) => View1Text2 );
...
}
#endregion ctor
...
private string _view1Text2;
public string View1Text2
{
get { return _view1Text2; }
set
{
if ( _view1Text2 != value )
{
_view1Text2 = value;
NotifyPropertyChanged( sr_view1Text2 );
}
}
}
Below - the results of testing: left side column - timing for constant string
property name, middle column - for expression derived property name and the right side column - for readonly string
variable which value is derived from expression only once.
Timings for "magic strings" property names and readonly string
variable property names are the same.
History
- 3rd May, 2016: Initial version