问题
Is there any way to stringify a member name in C# for .NET 4.0 like you would in C by using the #define str(s) #s macro?
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;
Re-factorization breaks the raise property changed event if I have Search in Strings disabled or breaks completely unrelated strings if it is enabled. Sometimes I won't notice until a UI element no longer responds to changes.
回答1:
No, unfortunately. Currently you would have to use something like PostSharp or NotifyPropertyWeaver to do this reliably.
Note that in C# 5 you'll be able to do this:
public void RaisePropertyChanged([CallerMemberName] string member = "")
{
}
And you would use it like so:
public Double MyDouble
{
get { return _MyDouble;}
set
{
_MyDouble = value;
RaisePropertyChanged();
}
}
And the C# 5 compiler will automatically fill in the the optional parameter.
回答2:
For your specific case of OnPropertyChanged the best you could do is the following (though not ideal obviously)...
this.OnPropertyChanged(x => x.Member);
...and...
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();
}
}
...along these lines....
回答3:
I'm not familiar with the C construct, but it sounds awfully like the nameof keyword introduced in C# 6 which is
used to obtain the simple (unqualified) string name of a variable, type, or member.
If we wire it in:
public Double MyDouble
{
get { return _MyDouble; }
set
{
_MyDouble = value;
RaisePropertyChanged(nameof(MyDouble));
}
}
...and set a property value, RaisePropertyChanged receives a string argument of "MyDouble".
来源:https://stackoverflow.com/questions/10252020/stringify-member-name-similar-to-define-strs-s-in-c