寻找一种干净的方法来以类型安全的方式发现方法的字符串名称。
以下是我对属性的看法,但我无法弄清楚如何为方法做到这一点。
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);
}
}
答案 0 :(得分:5)
几乎改为:
var expression = (MethodCallExpression)selector.Body;
return expression.Method.Name;
除了明显的例外,您需要Action<T>
选项来处理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;
}
答案 1 :(得分:1)
如果有帮助,我们的代码库使用以下内容:
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
答案 2 :(得分:0)
如果您恰好拥有System.Web.Mvc
,可以使用ExpressionHelper.GetExpressionText(expression)
,如下所示:
Expression<Func<Response, string>> expression = r => r.Message;
Assert.AreEqual("Message", ExpressionHelper.GetExpressionText(expression));
(Response
是一个带有Message属性的自定义类。)