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

时间:2015-03-13 13:44:47

标签: c# reflection expression-trees

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

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;
}

我可以使用以下代码获取Callback属性名称:

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

但是其他属性的相同代码不起作用:

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

它们之间的唯一区别是数据类型,因此我将Callback更改为int,并且代码不再适用于此属性。如果它是一个整数,为什么我不能这样得到属性的名称?

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:4)

问题是表达式树的类型 - 您试图表示类型Func<T, object>的委托,如果属性返回int,则表示需要转换。您只需要在源和目标类型中使该方法通用:

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

现在你应该可以做到:

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

我意识到这有点令人讨厌,但您可以通过通用的类型进行蹦床,因此您只需要推断单个类型参数:

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);

:)