我可以在不使用String传递方法名称的情况下编写方法名吗? (C#)

时间:2014-12-12 10:37:24

标签: c#

我有这门课:

class foo
{
   int val;
   public int Val
   {
      set{ val = values; },
      set{ val = values; }
   }
}

我需要将属性名称传递给DataBinding:

String propertyName = "Val";
ctrl.DataBindings.Add(propertyName, object, dataMember, true, DataSourceUpdateMode.Never);

我想做这样的事情:

propertyName = typeof(foo).methods.Val.toString();

5 个答案:

答案 0 :(得分:5)

如果您可以使用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中使用重构。

答案 1 :(得分:1)

从C#6开始,您可以使用nameof运算符:

ctrl.DataBindings.Add(nameof(foo.Val), /* other arguments as before */);

在C#6之前,在编译时没有非常简单的方法可以做到这一点。但是,一种选择是使用单元测试来检查所有属性名称是否为实际属性(使用反射进行检查)。

另请注意,在C#5中CallerMemberNameAttribute对实施INotifyPropertyChanged非常有用 - 但对您的案例并不有用。

使用表达式树的方法有效,但对我来说感觉有点笨拙。虽然技术要低得多,但简单的字符串常量和单元测试感觉更简单。

答案 2 :(得分:1)

如果您不使用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);

答案 3 :(得分:1)

我不知道您是否正在使用INotifyPropertyChanged,但有一些关于如何避免在这里使用“魔术字符串”的文章可能有用:

Implementing NotifyPropertyChanged without magic strings

typesafe NotifyPropertyChanged using linq expressions

答案 4 :(得分:0)

使用LINQ检查静态类型反射:http://blogs.clariusconsulting.net/kzu/statically-typed-reflection-with-linq/

你可以这样做:

string propertyName = Reflect<foo>.GetProperty(x => x.Val).Name;