如何获得强类型的给定类型的属性名称?

问题描述 投票:2回答:2

我希望能够使用强类型语法检索类型属性的名称。我已经有一个函数来获取实例的属性名称:

public static string PropertyName<T, TReturn>(this T obj, Expression<Func<T, TReturn>> property) where T : class 
{
    MemberExpression body = (MemberExpression) property.Body;
    if (body == null) throw new ArgumentException("The provided expression did not point to a property.");       
    return body.Member.Name;
}

可以这样调用:

Car car = new Car();
car.PropertyName(x => x.Wheels) //returns "Wheels"

我正在尝试创建另一个可以支持以下功能:

Type t = Typeof(Car);
t.PropertyName(x => x.Wheels) //should return "Wheels"

或者只是(甚至更好!):

Car.PropertyName(x => x.Wheels)

我该怎么做?

c# .net reflection expression-trees
2个回答
8
投票

您可以重写方法以使用它而无需创建实例:

var prop = ReflectionHelper.PropertyName<Car>(x => x.Wheels);

因为你不需要使用obj,因为你不需要它:

public static class ReflectionHelper
{
    public static string PropertyName<T>(Expression<Func<T, object>> property) where T : class 
    {
        MemberExpression body = (MemberExpression)property.Body;
        return body.Member.Name;
    }
}

请注意,返回类型不必是强类型的,它可以只是object


1
投票

@abatishchev示例仅在Wheels是引用类型时有效。

如果您有以下内容

public class Car
{
   public int ID;
}

你试着打电话给这个

var prop = ReflectionHelper.PropertyName<Car>(x => x.ID);

你会得到以下例外

InvalidCastException:无法将类型为“System.Linq.Expressions.UnaryExpression”的对象强制转换为“System.Linq.Expressions.MemberExpression”。

我认为这与您将值类型传递给表达式这一事实有关,因此必须将其装入对象中。如果传递引用类型,则不需要将其装箱到对象。

你可以做的是:

var prop = ReflectionHelper.PropertyName((Car x) => x.ID);

public static class ReflectionHelper
{
    public static string PropertyName<T, P>(Expression<Func<T, P>> property) 
        where T : class 
    {
        MemberExpression body = (MemberExpression)property.Body;
        return body.Member.Name;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.