从表达式()=>获取类名和属性名称MyClass.Name

时间:2011-02-18 10:44:06

标签: .net linq expression

这可能是重复的,但我找不到合适的问题。

我想从"MyClass.Name"获取() => MyClass.Name。如何定义方法参数以及如何将表达式转换为字符串?

2 个答案:

答案 0 :(得分:4)

这是Expression<Func<string>>,所以你可以:

void Foo(Expression<Func<string>> selector) {...}

void Foo<T>(Expression<Func<T>> selector) {...}

但是,请注意语法MyClass.Name是指 static 属性;如果你想要一个实例属性,你可能需要更像Expression<Func<MyClass,string>>的东西 - 例如:

static void Foo<TSource, TValue>(
    Expression<Func<TSource, TValue>> selector)
{

}
static void Main() {
     Foo((MyClass obj) => obj.Name);        
}

至于实施; 在这个简单的情况下,我们可以预期BodyMemberExpression,所以:

static void Foo<TSource, TValue>(
    Expression<Func<TSource, TValue>> selector)
{
    var member = ((MemberExpression)selector.Body).Member;
    Console.WriteLine(member.ReflectedType.Name + "." + member.Name);
}

然而,在一般情况下它更复杂。如果我们使用静态成员,这也将起作用:

static void Foo<TValue>(
    Expression<Func<TValue>> selector)
{
    var member = ((MemberExpression)selector.Body).Member;
    Console.WriteLine(member.ReflectedType.Name + "." + member.Name);
}

答案 1 :(得分:1)

这取决于Name是否为静态属性 1.如果它不是静态的,则MyClass.Name根本不是有效的语法。因此,我们假设在这种情况下,您希望从本地变量使用中获取class+property,如下所示:

var instance = new MyClass();
string result = GetClassAndPropertyName(() => instance.Name);

所以GetClassAndPropertyName的实现应该是这样的:

public static string GetClassAndPropertyName<T>(Expression<Func<T>> e)
{
    MemberExpression memberExpression = (MemberExpression) e.Body;
    return memberExpression.Member.DeclaringType.Name + "." + memberExpression.Member.Name;
}

您可以在Marc的答案中找到另一种语法。

2. Name属性也可以是静态的,这在我看来不太可能,但它会允许以下语法,这是您要求的语法:

string result = GetClassAndPropertyName(() => MyClass.Name);