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

3

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

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

2个回答

6

这是一个 Expression<Func<string>>,所以你可以拥有:

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

或者

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

请注意,语法MyClass.Name是指一个静态属性;如果您需要一个实例属性,您可能需要类似Expression<Func<MyClass,string>>的一些东西。例如:

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

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

关于实现; 在这个简单的案例中,我们可以期望Body是一个MemberExpression,因此:

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

Foo((MyClass obj) => obj.Name) 是我正在寻找的。谢谢。 - jgauffin

1

这要看 Name 是否是静态属性。
1.如果不是静态的,那么 MyClass.Name 就根本不是有效的语法。因此在这种情况下,假设您想从本地变量使用中获取 类+属性,请执行以下操作:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接