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);