【问题标题】:Can we modify this code to return the name of a method instead of a property?我们可以修改此代码以返回方法名称而不是属性吗?
【发布时间】:2013-09-14 17:35:13
【问题描述】:

寻找一种干净的方式来以类型安全的方式发现方法的字符串名称。

这是我拥有的属性,但我无法弄清楚如何为方法做这件事。

class Program
{
    class Customer
    {
        public String Id { get; set; }
    }

    public static String GetPropertyName<T>(
        Expression<Func<T, Object>> selector) where T : class
    {
        var expression = (MemberExpression)selector.Body;
        return expression.Member.Name;
    }

    static void Main(string[] args)
    {
        String propertyName = GetPropertyName<Customer>(c => c.Id);
    }
}

【问题讨论】:

  • 有趣。示例用法会是什么样子? GetMethodName&lt;Foo&gt;(f =&gt; f.Method)GetMethodName&lt;Foo&gt;(f =&gt; f.Method(valid, args)) 或其他?

标签: c#


【解决方案1】:

差不多改成:

    var expression = (MethodCallExpression)selector.Body;
    return expression.Method.Name;

有一个明显的例外,您将需要一个 Action&lt;T&gt; 选项来处理 void 方法。当然,您必须提供虚拟参数值 - 如果您真的想要您也可以获取这些值。

实际上,您的现有代码可能不够健壮;您可能需要放弃强制转换操作(将 int 装箱到对象中)。

public static string GetMethodName<T>(Expression<Func<T, Object>> selector) where T : class
{
    var expression = (MethodCallExpression)(selector.Body is UnaryExpression ? ((UnaryExpression)selector.Body).Operand : selector.Body);
    return expression.Method.Name;
}
public static string GetMethodName<T>(Expression<Action<T>> selector) where T : class
{
    var expression = (MethodCallExpression)(selector.Body is UnaryExpression ? ((UnaryExpression)selector.Body).Operand : selector.Body);
    return expression.Method.Name;
}

【讨论】:

    【解决方案2】:

    如果有帮助,我们的代码库使用以下内容:

    public class TypeHelper
    {
        private static PropertyInfo GetPropertyInternal(LambdaExpression p)
        {
            MemberExpression memberExpression;
    
            if (p.Body is UnaryExpression)
            {
                UnaryExpression ue = (UnaryExpression)p.Body;
                memberExpression = (MemberExpression)ue.Operand;
            }
            else
            {
                memberExpression = (MemberExpression)p.Body;
            }
            return (PropertyInfo)(memberExpression).Member;
        }
    
        public static string GetPropertyName<TObject>(Expression<Func<TObject, object>> p)
        {
            return GetPropertyNameInternal(p);
        }
    
        public static string GetPropertyName<TObject, T>(Expression<Func<TObject, T>> p)
        {
            return GetPropertyNameInternal(p);
        }
    
        public static string GetPropertyName<T>(Expression<Func<T>> p)
        {
            return GetPropertyNameInternal(p);
        }
    
        public static string GetPropertyName(Expression p)
        {
            return GetPropertyNameInternal((LambdaExpression) p);
        }
    
        private static string GetPropertyNameInternal(LambdaExpression p)
        {
            return GetPropertyInternal(p).Name;
        }
    
        public static PropertyInfo GetProperty<TObject>(Expression<Func<TObject, object>> p)
        {
            return GetPropertyInternal(p);
        }
    
        public static PropertyInfo GetProperty<TObject, T>(Expression<Func<TObject, T>> p)
        {
            return GetPropertyInternal(p);
        }
    
        public static PropertyInfo GetProperty<T>(Expression<Func<T>> p)
        {
            return GetPropertyInternal(p);
        }
    }
    

    这让你有能力做:

    var propertyName = TypeHelper.GetPropertyName<Customer>(c => c.Id);
    

    或者

    var propertyName = TypeHelper.GetPropertyName(() => this.Id); // If inside Customer class
    

    【讨论】:

      【解决方案3】:

      如果你碰巧有System.Web.Mvc,你可以使用ExpressionHelper.GetExpressionText(expression),像这样:

      Expression<Func<Response, string>> expression = r => r.Message;
      Assert.AreEqual("Message", ExpressionHelper.GetExpressionText(expression));
      

      Response 是具有 Message 属性的自定义类。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-04
        • 2015-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-17
        相关资源
        最近更新 更多