基于动态/表达式的方法获取类的属性类型?

时间:2015-10-07 03:19:35

标签: c# reflection lambda

我目前有一个获取对象属性类型的函数,可以在下面看到。

private static Type GetPropertyType<TClass, TResult>(Expression<Func<TClass, TResult>> propertyExpression)
{
    Type type = propertyExpression.Body.Type;
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        type = Nullable.GetUnderlyingType(type);
    }
    return type;
}

现在,问题是我需要有一个对象实例,我打算获取属性的类型,如下所示

var baseZoneTypeEntity = zoneTypeCollection.First();
Type t = GetPropertyType(() => baseZoneTypeEntity.BonusAmount);

我想要像你传递类而不是传递实例一样,所以

Type t = GetPropertyType<ZoneTypeClass>(_ => _.BonusAmount);

表达对我来说很新,我试图将其转换半小时已经无法使用。

你们可以帮我把它转换成一个基于对象的类吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

在你目前的方法中,你会写:

Type t = GetPropertyType<ZoneTypeClass, int>(_ => _.BonusAmount)

这是多余的,因为您必须传入实例或指定结果类型。您可以重写方法以不关心结果类型,但将其保留为object。这是可能的,因为您正在检查表达式主体,允许在您的问题中发布所需的行为(使用_ => _.Property)。

static Type GetPropertyType<TObject>(Expression<Func<TObject, object>> propertyExpression)
{
    var expression = propertyExpression.Body;
    var unaryExpression = expression as UnaryExpression;
    if (unaryExpression != null)
    {
        expression = unaryExpression.Operand;
    }
    Type type = expression.Type;
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        type = Nullable.GetUnderlyingType(type);
    }
    return type;
}

为什么奇怪的UnaryExpression if声明?如果您的属性类型不是object类型,则表达式将评估为_ => ((object)_.Property)UnaryExpression是类型转换部分,我们正在消除它。

答案 1 :(得分:0)

你需要将表达式参数更改为对象试试这个。

      private static Type GetPropertyType<TClass>(Expression<Func<TClass, object>> propertyExpression)
    {
        var unaryExpression = propertyExpression.Body as UnaryExpression;

        if (unaryExpression == null) return propertyExpression.Body.Type;

        var type = unaryExpression.Operand.Type;

        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>))
        {
            type = Nullable.GetUnderlyingType(type);
        }

        return type;
    }

更新:表达式主体需要转换为UnaryExpression,上面应该有效 然后你可以用它作为

 var type= GetPropertyType<CustomerEntity>(x => x.FirstName);

或者

    var type= GetPropertyType<ProductEntity>(_ => _.Price);