使用lambda表达式调用构建方法

本文关键字:构建 方法 调用 表达式 lambda 使用 | 更新日期: 2023-09-27 18:11:15

我正在构建一个方法,从System.ComponentModel.DataAnnotations中获取DisplayAttribute,以显示在属性的标签上。

[Display(Name="First Name")]
public string FirstName { get; set; }

方法运行良好:

string GetDisplay(Type dataType, string property)
{
    PropertyInfo propInfo = dataType.GetProperty(property);
    DisplayAttribute attr = propInfo.GetCustomAttributes(false).OfType<DisplayAttribute>().FirstOrDefault();
    return (attr == null) ? propInfo.Name : attr.Name;
}

方法的调用可以是:

lblNome.Text = GetDisplay(typeof(Person), "FirstName") + ":";

我可以使用更优雅的泛型,如:

string GetDisplay<T>(string property)
{
    PropertyInfo propInfo = typeof(T).GetProperty(property);
    DisplayAttribute attr = propInfo.GetCustomAttributes(false).OfType<DisplayAttribute>().FirstOrDefault();
    return (attr == null) ? propInfo.Name : attr.Name;
}

和呼叫:

GetDisplay<Person>("FirstName");

所以,我想让它更优雅使用lambda表达式把调用变成这样:

GetDisplay<Person>(p => p.FirstName);

问题是我怎样才能做到这一点?

使用lambda表达式调用构建方法

下面是我用来获取由lambda表达式给出的属性名的方法:

    public static string PropertyName<T1, T2>(this Expression<Func<T1, T2>> expression)
    {
        MemberExpression member = null;
        if (expression.Body is MemberExpression)
            member = expression.Body as MemberExpression;
        if (expression.Body is UnaryExpression && expression.Body.NodeType == ExpressionType.Convert)
            member = ((UnaryExpression)expression.Body).Operand as MemberExpression;
        if (member == null)
            throw new ArgumentException("Selector must point to a property or field.", "expression");
        return member.Member.Name;
    }

使用这个方法你可以只调用前面的方法:

string GetDisplay<T>(Expression<Func<T, object>> expression)
{
    return GetDisplay<T>(expression.PropertyName());
}