在编译时获取属性名称而不使用魔术字符串,类似于T4MVC概念

时间:2014-05-20 09:57:36

标签: c# reflection lambda metadata

有时,我需要获取与属性名称或表达式等效的字符串。大多数情况下,这是针对某些序列化或ORM映射。使用无关紧要。而不是将字符串键入"魔术字符串",例如

var sPropertyName = "PropertyId";

我使用反射,因此如果它发生变化,它会自动更新。例如:

    public void test()
    {
         var sPropertyName = GetPropertyName<Property>(x => x.PropertyId);
    }



    public static string GetPropertyName<T>(Expression<Func<T, object>> selector)
    {

        return (PropertyInfo)GetMemberInfoBySelector(selector);


    }

    public static MemberInfo GetMemberInfoBySelector(Expression selector)
    {
        Expression body = selector;
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }
        switch (body.NodeType)
        {
            case ExpressionType.Call:
                return (((System.Linq.Expressions.MethodCallExpression)body).Method);
            case ExpressionType.MemberAccess:
                return ((PropertyInfo)((MemberExpression)body).Member);
            case ExpressionType.Convert:
                {
                    UnaryExpression unaryExp = (UnaryExpression)body;
                    var op = unaryExp.Operand;
                    System.Linq.Expressions.MemberExpression memberExp = (MemberExpression)op;
                    return memberExp.Member;

                }
            default:
                throw new InvalidOperationException("Cannot retrieve member info from selector!");
        }


    }

有时,对于批处理或类似处理,这种情况经常被调用。当价值实际上是一个常数时,我觉得这是一种浪费,它会反映出来。如果它被大量使用,这可能会使事情变得相当缓慢。

我知道ASP.Net MVC存在一个工具 - T4MVC,它扫描文件并使用属性名创建静态类。

在这种情况下,理想的东西就是我可以使用say

var sPropertyName = GeneratedMetaData.MyNamespace.Property.PropertyId 

这有可能吗?我知道我可以在应用程序启动时自己存储这些常量,但想知道是否有类似T4MVC的自动内容。

或者也许其他做同样事情的方法?

0 个答案:

没有答案