0

假设我有一个具有以下签名的方法:

public void MyMethod(Func<int> expression)
{
    // Does work
}

我称这个方法如下:

int intProperty = 7;
MyMethod(() => intProperty);

他们是不是我可以在不使用 lambda 的情况下调用此方法?所以我希望它看起来像这样:

MyMethod(intProperty);

方法签名是否必须更改对我来说并不重要——我有点指望它。我尝试这样做的原因是,当初始属性作为我需要能够访问的函数传入时,您可以检查有关初始属性的其他信息。

我不相信在 MyMethod 中使用反射在这里会起作用,因为我想要有关原始参数的信息。它们是从函数中获取信息的方法,例如它的名称,这是我希望能够检索的。我已经能够做到这一点。因此,在上面的示例中,MyMethod 将能够判断传入的属性名称为 intProperty。

注意:这是一个简化的示例。我很清楚,如果这就是我想要的,我可以直接通过房产。但我想要有关 Func 在此处捕获的原始属性的其他信息,例如其原始名称。

4

2 回答 2

1

您不能为属性执行此操作,但您可以为类似属性的 getter 方法执行此操作。从 C#3.0 开始,您可以使用方法组隐式构建委托:

public void MyMethod(Func<int> expression) {
    // Does work
}
public int GetProperty() {
    return 123;
}
pubic void Test() {
    MyMethod(GetProperty /* NO PARENTHESES HERE!!! */);
}

删除方法名称后的括号会将调用表达式转换为方法组。不幸的是,这意味着属性没有可比的语法,因为访问属性不需要括号。

于 2013-03-08T13:58:52.847 回答
0

Using expressions

You mentioned that it doesn't matter if the method signature has to change. So why not change the method signature to:

public void MyMethod<T>(T source, Expression<Func<T, int>> expression)
{
    // Evaluate expression
}

MyMethod(this, x => x.property);

I won't go into too much detail here on parsing expression trees, but for more information, see this question on SO:

Retrieving Property name from lambda expression

Using reflection

You can use reflection to get information about the property as well. Drop the source parameter if you don't need to get the actual value of the property.

public void MyMethod(object source, string propertyName)
{
    var pi = source.GetType().GetProperty(propertyName);
    if (pi == null)
    {
        throw new Exception("property not found");
    }

    MyMethod(source, pi);
}

public void MyMethod(object source, PropertyInfo property)
{
    // Evaluate property
}

MyMethod(this, "Property");
于 2013-03-08T13:55:28.783 回答