Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 使用linq表达式更改typesafe NotifyProperty_Wpf_Mvvm_Expression Trees_Inotifypropertychanged - Fatal编程技术网

Wpf 使用linq表达式更改typesafe NotifyProperty

Wpf 使用linq表达式更改typesafe NotifyProperty,wpf,mvvm,expression-trees,inotifypropertychanged,Wpf,Mvvm,Expression Trees,Inotifypropertychanged,Form I具有以下代码,允许我们进行typesafe NotifyOfPropertyChange调用: public void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property) { var lambda = (LambdaExpression)property; MemberExpression memberExpression; if (

Form I具有以下代码,允许我们进行typesafe NotifyOfPropertyChange调用:

public void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property)
{
    var lambda = (LambdaExpression)property;
    MemberExpression memberExpression;
    if (lambda.Body is UnaryExpression)
    {
        var unaryExpression = (UnaryExpression)lambda.Body;
        memberExpression = (MemberExpression)unaryExpression.Operand;
    }
    else memberExpression = (MemberExpression)lambda.Body;
    NotifyOfPropertyChange(memberExpression.Member.Name);
 }
public void NotifyOfPropertyChange(表达式属性)
{
var lambda=(LambdaExpression)属性;
成员表达成员表达;
if(lambda.Body是一元表达式)
{
var unaryExpression=(unaryExpression)lambda.Body;
memberExpression=(memberExpression)unaryExpression.Operator;
}
else memberExpression=(memberExpression)lambda.Body;
NotifyOfPropertyChange(memberExpression.Member.Name);
}

这种方法与标准的简单字符串方法性能比较如何?有时我的属性会以非常高的频率变化。我使用这个防打字安全的方法安全吗?经过一些最初的测试,它似乎确实有一点不同。这种方法可能会导致多少CPU内存负载?

引起这种情况的代码是什么样子的?我猜是这样的:

NotifyOfPropertyChange(() => SomeVal);
这意味着:

NotifyOfPropertyChange(() => this.SomeVal);
它捕获了
这个
,这意味着每次都必须从头开始构造表达式树(使用
expression.Constant
)。然后每次都解析它。因此,开销绝对不是微不足道的


是不是太多了?这是一个只有你才能回答的问题,通过分析和了解你的应用程序。对于很多MVC的使用来说,这是可以的,但是(通常)这并不是在一个长期运行的紧密循环中。基本上,您需要根据所需的性能目标进行评测。

Emiel Jongerius对各种InotifyProperty更改的实现进行了良好的性能比较


底线是,如果您在UI上使用INotifyPropertyChanged进行数据绑定,那么不同版本的性能差异是微不足道的。

堆栈遍历速度较慢,lambda表达式甚至更慢。我们有类似于众所周知的lambda表达式的解决方案,但速度几乎和string literal一样快。看见

我在实现INotifyPropertyChanged的基类中使用了以下方法,它非常简单方便:

public void NotifyPropertyChanged()
    {
        StackTrace stackTrace = new StackTrace();

        MethodBase method = stackTrace.GetFrame(1).GetMethod();

        if (!(method.Name.StartsWith("get_") || method.Name.StartsWith("set_")))
        {
            throw new InvalidOperationException("The NotifyPropertyChanged() method can only be used from inside a property");
        }

        string propertyName = method.Name.Substring(4);

        RaisePropertyChanged(propertyName);
    }

我希望您也觉得它有用。:-)

使用事实标准怎么样

if (propName == value) return;
propName = value;
OnPropertyChanged("PropName");
然后创建一个自定义工具,根据此标准检查和重构代码文件。该工具可以是预构建任务,也可以在构建服务器上。
简单、可靠、可执行。

类型安全且无性能损失:NotifyPropertyWeaver扩展。它会在编译之前自动添加所有通知…

您可能会对此讨论感兴趣:请不要在多个问题上发送相同的答案。如果问题是重复的,请留下一条评论,说明这一点(或者如果你有足够的声誉,请标记)。如果它不是重复的,请根据所问的问题定制您的答案。perf comparations@Simon当然,在c#5中,新的呼叫者姓名属性使它几乎成为一个多余的问题