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 .net propertychange通知处理程序-字符串与表达式_Wpf_Expression_Inotifypropertychanged - Fatal编程技术网

Wpf .net propertychange通知处理程序-字符串与表达式

Wpf .net propertychange通知处理程序-字符串与表达式,wpf,expression,inotifypropertychanged,Wpf,Expression,Inotifypropertychanged,使用WPF使我成为INotifyPropertyChanged的粉丝。我喜欢使用一个helper,它接受一个表达式并以字符串形式返回名称(参见下面的示例代码)。然而,在我看到的很多应用程序中,我都是非常熟练的程序员,我看到了处理原始字符串的代码(参见下面的第二个示例)。所谓熟练,我指的是懂得如何使用表达式的MVP类型 对我来说,除了简单的重构之外,让编译器捕捉错误的机会使EXPRESSION方法变得更好。是否有支持使用我缺少的原始字符串的论点 干杯, 贝里尔 表达式帮助器示例: public s

使用WPF使我成为INotifyPropertyChanged的粉丝。我喜欢使用一个helper,它接受一个表达式并以字符串形式返回名称(参见下面的示例代码)。然而,在我看到的很多应用程序中,我都是非常熟练的程序员,我看到了处理原始字符串的代码(参见下面的第二个示例)。所谓熟练,我指的是懂得如何使用表达式的MVP类型

对我来说,除了简单的重构之外,让编译器捕捉错误的机会使EXPRESSION方法变得更好。是否有支持使用我缺少的原始字符串的论点

干杯, 贝里尔

表达式帮助器示例:

public static string GetPropertyName<T>(Expression<Func<T, object>> propertyExpression)
    {
        Check.RequireNotNull<object>(propertyExpression, "propertyExpression");
        switch (propertyExpression.Body.NodeType)
        {
            case ExpressionType.MemberAccess:
                return (propertyExpression.Body as MemberExpression).Member.Name;
            case ExpressionType.Convert:
                return ((propertyExpression.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
        }
        var msg = string.Format("Expression NodeType: '{0}' does not refer to a property and is therefore not supported", 
            propertyExpression.Body.NodeType);
        Check.Require(false, msg);
        throw new InvalidOperationException(msg);
    }
private static PropertyChangedEventArgs mobilePhoneNumberChangeArgs =
        ObservableHelper.CreateArgs<CustomerModel>(x => x.MobilePhoneNumber);
公共静态字符串GetPropertyName(表达式propertyExpression)
{
检查.RequireNotNull(propertyExpression,“propertyExpression”);
开关(propertyExpression.Body.NodeType)
{
case ExpressionType.MemberAccess:
返回(propertyExpression.Body作为MemberExpression).Member.Name;
大小写表达式类型。转换:
返回((propertyExpression.Body作为UnaryExpression)。操作数作为MemberExpression)。Member.Name;
}
var msg=string.Format(“表达式节点类型:{0}”未引用属性,因此不受支持”,
propertyExpression.Body.NodeType);
检查.Require(false,msg);
抛出新的InvalidOperationException(消息);
}
原始字符串示例代码(在某些ViewModelBase类型类中):

//
///如果此对象没有
///具有指定名称的公共属性。这
///方法在发布版本中不存在。
/// 
[条件(“调试”),调试步骤至]
public void VerifyPropertyName(字符串propertyName){
//验证属性名称是否与实数匹配,
//此对象的公共、实例属性。
if(TypeDescriptor.GetProperties(此)[propertyName]==null){
string msg=“无效的属性名称:”+propertyName;
if(ThrowOnInvalidPropertyName)抛出新异常(msg);
else调试失败(msg);
}
}
/// 
///返回是否引发异常,或者是否使用了Debug.Fail()
///将无效的属性名称传递给VerifyPropertyName方法时。
///默认值为false,但单元测试使用的子类可能会
///重写此属性的getter以返回true。
/// 
受保护的虚拟bool ThrowOnInvalidPropertyName{get;private set;}
对我来说,除了简单的重构之外,让编译器捕捉错误的机会使EXPRESSION方法变得更好。是否有支持使用我缺少的原始字符串的论点

我个人同意,在大多数情况下,在我自己的代码中使用表达式方法

但是,我知道有两个原因可以避免这种情况:

  • 这一点不太明显,尤其是对于经验较少的.NET开发人员。写入
    RaisePropertyChanged(()=>this.MyProperty)对于人们来说并不总是像
    RaisePropertyChanged(“MyProperty”),并且与框架示例不匹配,等等

  • 使用表达式会带来一些性能开销。就我个人而言,我觉得这并不是一个真正有意义的原因,因为这通常用于数据绑定场景(由于反射的使用已经很慢了),但这可能是一个有效的问题

  • 对我来说,除了简单的重构之外,让编译器捕捉错误的机会使EXPRESSION方法变得更好。是否有支持使用我缺少的原始字符串的论点

    我个人同意,在大多数情况下,在我自己的代码中使用表达式方法

    但是,我知道有两个原因可以避免这种情况:

  • 这一点不太明显,尤其是对于经验较少的.NET开发人员。写入
    RaisePropertyChanged(()=>this.MyProperty)对于人们来说并不总是像
    RaisePropertyChanged(“MyProperty”),并且与框架示例不匹配,等等

  • 使用表达式会带来一些性能开销。就我个人而言,我觉得这并不是一个真正有意义的原因,因为这通常用于数据绑定场景(由于反射的使用已经很慢了),但这可能是一个有效的问题

  • 使用该方法的好处是,它支持基于ICustomTypeDescriptor实现的动态属性场景,其中该实现可以有效地为正在描述的类型动态创建动态属性元数据。考虑一个数据集,它的“属性”是由结果集决定的,例如,它被填充。p> 这是表达式不提供的,因为它基于实际的类型信息(一件好事)与字符串相反。

    使用该方法的好处是,它支持基于ICustomTypeDescriptor实现的动态属性场景,其中实现可以有效地动态创建所描述类型的动态属性元数据。考虑一个数据集,它的“属性”是由结果集决定的,例如,它被填充。p>
    然而,这是表达式没有提供的,因为它基于实际的类型信息(这是一件好事),而不是字符串。

    我在这方面花费的时间比我预期的要多,但确实找到了一个安全性/可重构性和性能完美结合的解决方案。良好的背景阅读和使用反射的替代解决方案是必要的。我更喜欢Sacha Barber的解决方案(背景)

    其思想是为将参与更改通知的属性使用表达式帮助器,但只对其进行一次命中,方法是将生成的PropertyChangedEventArgs存储在视图模型中。例如:

    public static string GetPropertyName<T>(Expression<Func<T, object>> propertyExpression)
        {
            Check.RequireNotNull<object>(propertyExpression, "propertyExpression");
            switch (propertyExpression.Body.NodeType)
            {
                case ExpressionType.MemberAccess:
                    return (propertyExpression.Body as MemberExpression).Member.Name;
                case ExpressionType.Convert:
                    return ((propertyExpression.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
            }
            var msg = string.Format("Expression NodeType: '{0}' does not refer to a property and is therefore not supported", 
                propertyExpression.Body.NodeType);
            Check.Require(false, msg);
            throw new InvalidOperationException(msg);
        }
    
    private static PropertyChangedEventArgs mobilePhoneNumberChangeArgs =
            ObservableHelper.CreateArgs<CustomerModel>(x => x.MobilePhoneNumber);
    
    <代码