是否可以在不使用字符串传递方法名称的情况下编写方法名称?(C#)
本文关键字:方法 情况下 字符串 是否 | 更新日期: 2023-09-27 18:34:05
我有这个类:
class foo
{
int val;
public int Val
{
set{ val = values; },
set{ val = values; }
}
}
我需要将属性名称传递给数据绑定:
String propertyName = "Val";
ctrl.DataBindings.Add(propertyName, object, dataMember, true, DataSourceUpdateMode.Never);
我想做这样的事情:
propertyName = typeof(foo).methods.Val.toString();
如果可以使用 C#6,则有 nameof
运算符,它就是这样做的。
string propertyName = nameof(foo.Val);
如果使用 C# 5,则可以利用表达式树:
public static string GetPropertyName<TParent>(Expression<Func<TParent, object>> prop)
{
var expr = prop.Body;
if (expr.NodeType == ExpressionType.Convert)
expr = ((UnaryExpression)expr).Operand;
if (expr.NodeType == ExpressionType.MemberAccess)
return ((MemberExpression)expr).Member.Name;
throw new ArgumentException("Invalid lambda", "prop");
}
像这样使用此帮助程序函数(假设它在 ReflectionHelper
类中):
string propertyName = ReflectionHelper.GetPropertyName<foo>(x => x.Val);
这样,您就可以在 IDE 中安全地使用重构。
如果不使用 C# 6,则需要传递一个Expression<Func<T>>
。
然后,您可以使用该对象执行此操作(如果要传递属性):
private string GetPropertyName(Expression<Func<T>> propertyExpession)
{
//the cast will always succeed if properly used
MemberExpression memberExpression = (MemberExpression)propertyExpression.Body;
string propertyName = memberExpression.Member.Name;
return propertyName;
}
你会这样使用:
var propName = GetPropertyName(() => this.Val);
我不知道
你是否正在使用INotifyPropertyChanged,但这里有一些关于如何避免使用"魔术字符串"的文章,这些文章可能会有用:
实现 NotifyPropertyChanged 没有魔术字符串
类型安全 通知属性已使用 linq 表达式更改
从 C# 6 开始,可以使用 nameof
运算符:
ctrl.DataBindings.Add(nameof(foo.Val), /* other arguments as before */);
在 C# 6 之前,没有真正简单的方法可以在编译时执行此操作。但是,一种选择是进行单元测试,以检查所有属性名称是否都是实际属性(使用反射进行检查)。
另请注意,在 C# 5 中,有CallerMemberNameAttribute
它对实现INotifyPropertyChanged
很有用 - 但对你的情况没有那么有用。
使用表达式树的方法有效,但对我来说感觉有些笨拙。虽然技术要低得多,但简单的字符串常量和单元测试感觉要简单一些。
使用 LINQ 签出静态类型反射:http://blogs.clariusconsulting.net/kzu/statically-typed-reflection-with-linq/
你可以做:
string propertyName = Reflect<foo>.GetProperty(x => x.Val).Name;