无法用 lambda 表达式替换字符串 propertyName 参数
Can't replace string propertyName parameter with lambda expression
我使用以下代码从 DataAnnotations 获取属性:
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property .GetCustomAttributes(attrType, false).First();
}
感谢用户:jgauffin
我想通过传递 lambda 表达式而不是字符串来改进他的解决方案:
public static T GetAttributeFrom<T>(this object instance, Expression<Func<T>> propertyExpression) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(GetPropertyNameFromLambdaExpression(propertyExpression));
return (T)property.GetCustomAttributes(attrType, false).First();
}
以及我从这个表达式中获取真实 属性 名称的方法:
public static string GetPropertyNameFromLambdaExpression<T>(Expression<Func<T>> propertyAsExpression)
{
var memberExpression = propertyAsExpression.Body as MemberExpression;
var propertyInfo = memberExpression.Member as PropertyInfo;
if (memberExpression != null && propertyInfo != null)
{
return memberExpression.Member.Name;
}
throw new ArgumentException(propertyAsExpression.ToString());
}
如果我尝试这样的事情:
var id = this.GetAttributeFrom<RangeAttribute>(()=> Id).Maximum;
我收到这个错误:
Cannot convert expression type 'int' to return type 'RangeAttribute'
我该如何解决这个问题?
您同时使用泛型类型 T 作为 属性 和 属性 的类型。尝试从以下开始:
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute {
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property.GetCustomAttributes(attrType, false).First();
}
public static T GetAttributeFrom<T, U>(this object instance, Expression<Func<U>> propertyExpression) where T : Attribute {
var attrType = typeof(T);
var property = instance.GetType().GetProperty(GetPropertyNameFromLambdaExpression<U>(propertyExpression));
return (T)property.GetCustomAttributes(attrType, false).First();
}
public static string GetPropertyNameFromLambdaExpression<U>(Expression<Func<U>> propertyAsExpression) {
var memberExpression = propertyAsExpression.Body as MemberExpression;
var propertyInfo = memberExpression.Member as PropertyInfo;
if (memberExpression != null && propertyInfo != null) {
return memberExpression.Member.Name;
}
throw new ArgumentException(propertyAsExpression.ToString());
}
那么你可以这样调用:
var max = this.GetAttributeFrom<RangeAttribute, int>(() => Id).Maximum;
你不能省略第二种 (GetAttributeFrom<RangeAttribute>(() => Id)
): C# generics can't infer second parameter?.
我使用以下代码从 DataAnnotations 获取属性:
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property .GetCustomAttributes(attrType, false).First();
}
感谢用户:jgauffin
我想通过传递 lambda 表达式而不是字符串来改进他的解决方案:
public static T GetAttributeFrom<T>(this object instance, Expression<Func<T>> propertyExpression) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(GetPropertyNameFromLambdaExpression(propertyExpression));
return (T)property.GetCustomAttributes(attrType, false).First();
}
以及我从这个表达式中获取真实 属性 名称的方法:
public static string GetPropertyNameFromLambdaExpression<T>(Expression<Func<T>> propertyAsExpression)
{
var memberExpression = propertyAsExpression.Body as MemberExpression;
var propertyInfo = memberExpression.Member as PropertyInfo;
if (memberExpression != null && propertyInfo != null)
{
return memberExpression.Member.Name;
}
throw new ArgumentException(propertyAsExpression.ToString());
}
如果我尝试这样的事情:
var id = this.GetAttributeFrom<RangeAttribute>(()=> Id).Maximum;
我收到这个错误:
Cannot convert expression type 'int' to return type 'RangeAttribute'
我该如何解决这个问题?
您同时使用泛型类型 T 作为 属性 和 属性 的类型。尝试从以下开始:
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute {
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property.GetCustomAttributes(attrType, false).First();
}
public static T GetAttributeFrom<T, U>(this object instance, Expression<Func<U>> propertyExpression) where T : Attribute {
var attrType = typeof(T);
var property = instance.GetType().GetProperty(GetPropertyNameFromLambdaExpression<U>(propertyExpression));
return (T)property.GetCustomAttributes(attrType, false).First();
}
public static string GetPropertyNameFromLambdaExpression<U>(Expression<Func<U>> propertyAsExpression) {
var memberExpression = propertyAsExpression.Body as MemberExpression;
var propertyInfo = memberExpression.Member as PropertyInfo;
if (memberExpression != null && propertyInfo != null) {
return memberExpression.Member.Name;
}
throw new ArgumentException(propertyAsExpression.ToString());
}
那么你可以这样调用:
var max = this.GetAttributeFrom<RangeAttribute, int>(() => Id).Maximum;
你不能省略第二种 (GetAttributeFrom<RangeAttribute>(() => Id)
): C# generics can't infer second parameter?.