【问题标题】:Strongly typed properties declarations - is this code safe?强类型属性声明——这段代码安全吗?
【发布时间】:2011-05-15 01:54:36
【问题描述】:

我想知道以下代码是否“安全”。 “安全”是指我不依赖于某些特定的编译器版本或未记录的功能。 我想获取带有属性/字段名称的字符串,但我想使用强类型声明它(我希望编译器检查特定字段/属性是否存在)。 我的方法是这样的:

string GetPropertyName<T>(Expression<Func<T, object>> expression)
{
    if (expression.Body is UnaryExpression)
    {
        var operand = ((UnaryExpression)expression.Body).Operand.ToString();
        return operand.Substring(operand.IndexOf(".") + 1);
    }
    else if (expression.Body is MemberExpression)
    {
        return ((MemberExpression)expression.Body).Member.Name;
    }
    else
    {
        throw new NotImplementedException();
    }            
}

这就是我想使用它的方式:

class Foo
{
    public string A { get; set; }
    public Bar B { get; set; }
}

class Bar
{
    public int C { get; set; }
    public Baz D { get; set; }
}

class Baz
{
    public int E { get; set; }
}


GetPropertyName<Foo>(x => x.A)
GetPropertyName<Foo>(x => x.B)
GetPropertyName<Foo>(x => x.B.C)
GetPropertyName<Foo>(foo => foo.B.D.E)

提前感谢您的帮助。

【问题讨论】:

    标签: c# .net strong-typing


    【解决方案1】:

    我不确定ToString 方法的输出是否有任何保证。文档只是说它“返回Expression的文本表示”

    (我怀疑输出不太可能在不同的平台/版本之间发生变化,但是当您的目标是使用强类型、编译时检查等时,我有点不愿意依赖它。)

    这是我在不使用ToString 的情况下执行类似操作的方法:

    public static string GetPropertyName<T>(Expression<Func<T, object>> e)
    {
        MemberExpression me;
        switch (e.Body.NodeType)
        {
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
                var ue = e.Body as UnaryExpression;
                me = ((ue != null) ? ue.Operand : null) as MemberExpression;
                break;
            default:
                me = e.Body as MemberExpression;
                break;
        }
    
        if (me == null)
            throw new ArgumentException("Expression must represent field or property access.", "e");
    
        var stack = new Stack<string>();
    
        do
        {
            stack.Push(me.Member.Name);
            me = me.Expression as MemberExpression;
        } while (me != null);
    
        return string.Join(".", stack);    // use "stack.ToArray()" on .NET 3.5
    }
    

    【讨论】:

      【解决方案2】:

      我认为你的代码还可以。我没有看到任何问题。要深入了解这一点,我建议您也阅读this articlethis one

      【讨论】:

        【解决方案3】:
            public static string GetPropertyName<T>(Expression<Func<T, object>> e)
            {
                if (e.Body is MemberExpression)
                    return ((MemberExpression)e.Body).Member.Name;
                else if (e.Body is UnaryExpression)
                    return ((MemberExpression)((UnaryExpression)e.Body).Operand).Member.Name;
        
                throw new ArgumentException("Expression must represent field or property access.", "e");
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-29
          • 2013-02-20
          • 1970-01-01
          • 2023-04-10
          • 1970-01-01
          • 2011-05-18
          相关资源
          最近更新 更多