如何获取使用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#中有什么好的干净的方法可以做到这一点吗?
您无法详细调查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