如何获取使用lambda作为参数发送的属性的名称

本文关键字:参数 属性 lambda 何获取 获取 | 更新日期: 2023-09-27 18:21:08

我可以有这样的方法:

public void MyMethod<T, TResult>( string propertyName, ... ){
    var name = propertyName;
    return {property with correct name from some object that is of type TResult}
}

这样称呼它:

MyMethod<SomeClass>("SomePropertyName");

获取方法内部的属性名称。但是,我不喜欢将该propertyname作为字符串发送,以防将来SomeClass发生更改,并且编译器也无法验证propertyname是否与类型为TResult的属性匹配。

我更愿意这样称呼它:

MyMethod<SomeClass>(c => c.SomePropertyName);

但我不确定我的方法会是什么样子。我尝试过这种变体:

public void MyMethod<T>( Func<T,TResult> property, ... ){
    var name = {do some cleverness on property here to extract the actual name of the property inside the expression};
    return {property with correct name from some object that is of type TResult}
}

在C#中有什么好的干净的方法可以做到这一点吗?

如何获取使用lambda作为参数发送的属性的名称

您无法详细调查Func<>委托。你想审问一个Expression。。像这样的东西(没有测试……但应该很接近):

public void MyMethod<T>(Expression<Func<T,TResult>> expr, ... ){
    var expression = (MemberExpression)expr.Body;
    var name = expression.Member.Name;
    // .. the rest here using "name"
}

用法相同:

MyMethod<User>(u => u.UserId); // name will be "UserId"

这就是我为RaisePropertyChanged方法执行此操作的方式

internal static class PropertySupport
{
    public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
    {
        if (propertyExpression == null)
        {
            throw new ArgumentNullException("propertyExpression");
        }
        var memberExpression = propertyExpression.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new ArgumentException("propertyExpression");
        }
        var property = memberExpression.Member as PropertyInfo;
        if (property == null)
        {
            throw new ArgumentException("propertyExpression");
        }
        var getMethod = property.GetGetMethod(true);
        if (getMethod.IsStatic)
        {
            throw new ArgumentException("propertyExpression");
        }
        return memberExpression.Member.Name;
    }
}

以及在使用PropertySupport的方法中:

protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
    var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
    this.RaisePropertyChanged(propertyName);
}

我可以简单地将其与一起使用

RaisePropertyChanded<String>(() => this.MyString);

正如您所看到的,lambda非常简单。

〔callermembername〕对您有用吗?你会像这样使用它:

public void MyMethod<T>([CallerMemberName]string caller = null){
    //leave caller blank and it will put the name of the calling member in as a string
}

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute(v=vs.110).aspx