无法使用此代码和表达式 api 获取此 属性 名称

Cannot get this property name using this code and expression api

我有以下 class,我需要获取其 属性 名称:

public class PMLButtonData
{
    public int BackgroundColorID
    {
        get;
        set;
    }

    public string Callback
    {
        get;
        set;
    }
}

我正在使用这个函数来获取名字

public static string GetPropertyName<T>(Expression<Func<T, object>> lambda)
{
    MemberExpression member = lambda.Body as MemberExpression;
    PropertyInfo property = member.Member as PropertyInfo;

    return property.Name;
}

我可以使用此代码获取回调 属性 名称:

string name = GetPropertyName<PMLButtonData>(x => x.Callback);

但是另一个 属性 的相同代码不起作用:

string name = GetPropertyName<PMLButtonData>(x => x.BackgroundColorID);

它们之间的唯一区别是数据类型,所以我将回调更改为 int 并且代码不再适用于此 属性。如果 属性 是整数,为什么我不能通过这种方式获取它的名称?

我猜它首先将 int 装箱到 object。试试这个签名:

public static string GetPropertyName<T, T2>(Expression<Func<T, T2>> lambda)

问题出在表达式树的类型上 - 您试图表示 Func<T, object> 类型的委托,如果 属性 returns 和 int ,这意味着它需要转换。您只需要在源 和目标 类型中使方法通用:

public static string GetPropertyName<TSource, TTarget>
    (Expression<Func<TSource, TTarget>> lambda)

现在你应该可以做到:

string name = GetPropertyName<PMLButtonData, int>(x => x.BackgroundColorID);

我知道这有点烦人,但您可以通过泛型 type 进行 trampoline,因此您只需要推断一个类型参数:

public static class PropertyName<TSource>
{
    public static string Get<TTarget>(Expression<Func<TSource, TTarget>> lambda)
    {           
        // Use casts instead of "as" to get more meaningful exceptions.
        var member = (MemberExpression) lambda.Body;
        var property = (PropertyInfo) member.Member;
       return property.Name;
    }
}

然后:

string name = PropertyName<PMLButtonData>.Get(x => x.BackgroundColorID);

当然,在 C# 6 中你不需要这些废话:

string name = nameof(PMLButtonData.BackgroundColorId);

:)