简体   繁体   English

强类型属性声明-此代码安全吗?

[英]Strongly typed properties declarations - is this code safe?

I'm wondering if following code is "safe". 我想知道以下代码是否“安全”。 By "safe" I mean that I don't depend on some specific compiler version or undocumented feature. “安全”是指我不依赖某些特定的编译器版本或未记录的功能。 I want to get string with property / field name, but I want to declare it using strong typing (I want the compiler to check if specific field / property exists). 我想获取带有属性/字段名称的字符串,但是我想使用强类型声明它(我希望编译器检查特定的字段/属性是否存在)。 My method looks like this: 我的方法如下所示:

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();
    }            
}

And here is how I want to use it: 这是我要使用的方式:

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)

Thanks in advance for help. 在此先感谢您的帮助。

I'm not sure that the output of the ToString method is guaranteed in any way. 我不确定以任何方式保证ToString方法的输出。 The documentation just says that it "returns a textual representation of the Expression " . 该文档只是说它“返回Expression的文本表示形式”

(I suspect that the output is unlikely to change across different platforms/versions, but I'd be a bit reluctant to rely on it when your aim is to use strong typing, compile-time checks etc.) (我怀疑输出可能不会在不同的平台/版本上发生变化,但是当您的目标是使用强类型化,编译时检查等时,我有点不愿意依赖它)

Here's my method that does something similar without using ToString : 这是我的方法,无需使用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
}

I think you code is okay. 我认为您的代码还可以。 I don't see any problems. 我没看到任何问题。 To get a little deep into this, I recommend you read this article and this one , too. 为了对此有所了解,我建议您也阅读本文这篇 文章

    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");
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM