0

有什么方法可以像在 C 中那样使用#define str(s) #s宏在 C# 中为 .NET 4.0 字符串化成员名称?

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;

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

4

3 回答 3

7

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

请注意,在 C# 5 中,您将能够做到这一点:

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

你会像这样使用它:

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

并且 C# 5 编译器会自动填写可选参数。

于 2012-04-20T19:05:26.667 回答
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();
    }
}

......沿着这些线......

于 2012-04-20T19:14:25.657 回答
0

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

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

如果我们将其接线:

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

        RaisePropertyChanged(nameof(MyDouble));
    }
}

...并设置一个属性值,RaisePropertyChanged接收一个字符串参数“MyDouble”。

于 2018-05-15T10:22:39.863 回答