之前的文章中曾有提供过这样一个获取属性选取表达式的目标属性名称的方法:

        /// <summary>
        /// 获取属性的名称
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <typeparam name="PT">属性类型</typeparam>
        /// <param name="表达式">获取属性的表达式</param>
        /// <returns>属性的名称</returns>
        public static string GetPropertyName<T,PT>(Expression<Func<T, PT>> 表达式)
        {
            string rtn = string.Empty;
            if (表达式.Body is UnaryExpression)
            {
                rtn = ((MemberExpression)((UnaryExpression)表达式.Body).Operand).Member.Name;
            }
            else if (表达式.Body is MemberExpression)
            {
                rtn = ((MemberExpression)表达式.Body).Member.Name;
            }
            else if (表达式.Body is ParameterExpression)
            {
                rtn = 表达式.Body.Type.Name;
            }
            return rtn;
        }

那么获取属性的类型想来也不难吧?

然而一试才发现,那个名为Member的MemberInfo类型属性中根本没有获取类型的相关属性。

不过我在调试中发现,其实这个属性值的真实类型是System.Reflection.RuntimePropertyInfo,而这个类型具有一个PropertyType属性,能够正确返回目标属性的类型。

这不就简单了嘛!把Member强制转换成RuntimePropertyInfo不就OK了?

可是,还是不行~

RuntimePropertyInfo类型貌似是非公开的,除了调试环境下,我们无法使用也无法查看它,写在代码里是没法进行编译的。

image

对象浏览器里都找不到这个神秘的类型……

那么怎么办呢?反射之!

反射获取属性值功能的扩展代码:

/// <summary>
    /// 通过反射获取对象的指定属性值
    /// </summary>
    /// <param name="o"></param>
    /// <param name="属性名">属性名</param>
    /// <returns>属性值</returns>
    public static object GetPropertyValue(this object o, string 属性名)
    {
        var t = o.GetType();
        return t.GetProperty(属性名).GetValue(o, null);
    }

然后就可以搞定了:

        /// <summary>
        /// 获取属性的类型
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <typeparam name="PT">属性类型</typeparam>
        /// <param name="表达式">获取属性的表达式</param>
        /// <returns>属性的类型</returns>
        public static Type GetPropertyType<T, PT>(Expression<Func<T, PT>> 表达式)
        {
            Type rtn = null;
            if (表达式.Body is UnaryExpression)
            {
                rtn = ((MemberExpression)((UnaryExpression)表达式.Body).Operand).Member.GetPropertyValue("PropertyType") as Type;
            }
            else if (表达式.Body is MemberExpression)
            {
                rtn = ((MemberExpression)表达式.Body).Member.GetPropertyValue("PropertyType") as Type;
            }
            else if (表达式.Body is ParameterExpression)
            {
                rtn = 表达式.Body.Type;
            }
            return rtn;
        }

亲测可用:

Reflection处理函数.GetPropertyType((string s) => s.Length).FullName
//输出结果为:System.Int32
转载此文章时须注明转载自”SkyD(斯克迪亚)开发者博客“,并保留此文章的Url链接

作者信息

昵称
斯克迪亚

查看其所发布的所有文章

总积分
2440
注册时间
(2018年5月4日 19:06)

评论

目前还没有任何评论。

[切换到移动版页面]