Stringify成员名称类似于C中的#define str(s)#s

时间:2012-04-20 19:01:02

标签: c# .net inotifypropertychanged

有没有办法在C#for .NET 4.0中字符串化成员名称,就像在C中使用#define str(s) #s宏一样?

public Double MyDouble
{
    get { return _MyDouble;}
    set 
    { 
        _MyDouble = value; 
        RaisePropertyChanged("MyDouble");
        // The below item would refactor correctly if C# had a stringify pre-processor
        // RaisePropertyChanged(str(MyDouble));
    }
}
private Double _MyDouble;

如果我已禁用Search in Strings,则重新分解会中断raise属性更改事件,如果已启用,则会中断完全不相关的字符串。有时我不会注意到UI元素不再响应更改。

3 个答案:

答案 0 :(得分:7)

不,不幸的是。目前,您必须使用PostSharp或NotifyPropertyWeaver之类的东西来可靠地执行此操作。

请注意,在C#5中,您将能够执行此操作:

public void RaisePropertyChanged([CallerMemberName] string member = "")
{
}

你会像这样使用它:

public Double MyDouble
{
    get { return _MyDouble;}
    set 
    { 
        _MyDouble = value; 
        RaisePropertyChanged();
    }
}

C#5编译器将自动填写可选参数。

答案 1 :(得分:2)

对于OnPropertyChanged的特定情况,您可以做的最好的事情如下(虽然显然不是很理想)......

this.OnPropertyChanged(x => x.Member);

......和......

protected void OnPropertyChanged(Expression<Func<T, object>> property)
{
    var propertyName = GetPropertyName(property.Body);
    if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private static string GetPropertyName(Expression expression)
{
    switch (expression.NodeType)
    {
        case ExpressionType.MemberAccess:
            var memberExpression = (MemberExpression)expression;
            var supername = GetPropertyName(memberExpression.Expression);

            if (String.IsNullOrEmpty(supername))
                return memberExpression.Member.Name;

            return String.Concat(supername, '.', memberExpression.Member.Name);

        case ExpressionType.Call:
            var callExpression = (MethodCallExpression)expression;
            return callExpression.Method.Name;

        case ExpressionType.Convert:
            var unaryExpression = (UnaryExpression)expression;
            return GetPropertyName(unaryExpression.Operand);

        case ExpressionType.Parameter:
            return String.Empty;

        default:
            throw new ArgumentException();
    }
}

......沿着这些方向......

答案 2 :(得分:0)

我不熟悉C构造,但听起来非常像C#6中引入的nameof关键字

  

用于获取变量的简单(非限定)字符串名称,   类型或成员。

如果我们将其连接到:

public Double MyDouble
{
    get { return _MyDouble; }
    set
    {
        _MyDouble = value;

        RaisePropertyChanged(nameof(MyDouble));
    }
}

...并设置属性值,RaisePropertyChanged接收字符串参数&#34; MyDouble&#34;。