Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.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
C# 使用lambda标识属性名_C#_Properties_Lambda - Fatal编程技术网

C# 使用lambda标识属性名

C# 使用lambda标识属性名,c#,properties,lambda,C#,Properties,Lambda,我对以下代码有一个问题: public class MyClass : INotifyPropertyChanged { private bool _myProp; public bool MyProp { get { return _myProp; } set { _myProp = value; RaisePropertyChanged(()

我对以下代码有一个问题:

public class MyClass : INotifyPropertyChanged
{
    private bool _myProp;
    public bool MyProp
    {
        get { return _myProp; }
        set
        {
            _myProp = value;                
            RaisePropertyChanged(() => MyProp);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
这可能不是识别物业名称的最佳方式,但我以前使用过它,即使是在同一个项目中;但是,上面的代码不会编译。有几个解决办法;其中一些可能是比上面更好的解决方案,但是,我仍然想找出为什么这不起作用

我得到的具体编译错误是:

error CS1660: Cannot convert lambda expression to type 'string' because it is not a delegate type

您需要一个方法来接受
表达式
,将属性名称提取为字符串,然后用它引发
PropertyChanged
事件。它不会自动完成。我通常将其作为一种扩展方法,以避免反复实现相同的代码或将其放在基类中:

public static class RaisePropertyChangedExtensions
{
    public static void RaisePropertyChanged<T>(
        this IRaisePropertyChanged raisePropertyChangedImpl,
        Expression<Func<T>> expr)
    {
        var memberExprBody = expr.Body as MemberExpression;
        string property = memberExprBody.Member.Name;
        raisePropertyChangedImpl.RaisePropertyChanged(property);
    }
}
…用法与您的问题完全相同:

this.RaisePropertyChanged(() => MyProp);

当然,您始终可以在视图模型上使用此方法-只需删除泛型参数并将视图模型类型传递给函数。

您需要使用表达式:

public static string GetPropertyName<T, TPropValue>(this Expression<Func<T, TPropValue>> propertySelector) where T : class
{
    Condition.Requires(propertySelector, "propertySelector").IsNotNull();

    var memberExpr = propertySelector.Body as MemberExpression;
    if (memberExpr == null)
         throw new ArgumentException("Provider selector is not property selector.");

    var propInfo = memberExpr.Member as PropertyInfo;       
    if (propInfo == null)
         throw new NotSupportedException("You can properties only.");

    return propInfo.Name;
}

protected void RaisePropertyChanged(Expression<Func<MyClass, string>> propSelector) 
{  
   if (PropertyChanged != null)
   {
       var propertyName = propertySelecotr.GetPropertyName();
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
   }
}

签出新的CallerMemberName属性。我只是通过mvvm light发现了这一点,但我再也不会以旧方式更改notify属性了


为什么不干脆把
RaisePropertyChanged(“MyProp”)?@DmitryBychenko这是重构不友好的。是的,正如我遇到这个问题时所发生的那样,这就是我过去经常遇到的问题。我只是想知道为什么它不起作用。它确实起作用了——正如我所说,我的问题并不是说我什么都做不到,而是我想知道为什么使用()=>属性名不起作用。抱歉,我的误解。
public static string GetPropertyName<T, TPropValue>(this Expression<Func<T, TPropValue>> propertySelector) where T : class
{
    Condition.Requires(propertySelector, "propertySelector").IsNotNull();

    var memberExpr = propertySelector.Body as MemberExpression;
    if (memberExpr == null)
         throw new ArgumentException("Provider selector is not property selector.");

    var propInfo = memberExpr.Member as PropertyInfo;       
    if (propInfo == null)
         throw new NotSupportedException("You can properties only.");

    return propInfo.Name;
}

protected void RaisePropertyChanged(Expression<Func<MyClass, string>> propSelector) 
{  
   if (PropertyChanged != null)
   {
       var propertyName = propertySelecotr.GetPropertyName();
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
   }
}
RaisePropertyChanged(myClass => myClass.MyProp);