我已经构建了一个方法,如果在属性上找到属性的实例,则返回一个属性实例:
public static U GetPropertyAttribute<T, TProperty, U>(this T instance, Expression<Func<T, TProperty>> propertySelector, U attribute) where U : Attribute
{
return Attribute.GetCustomAttribute(instance.GetType().GetProperty((propertySelector.Body as MemberExpression).Member.Name), typeof(U), true) as U;
}
为了获取实例,我必须调用:
var cc = new CustomClass();
cc.GetPropertyAttribute(x => x.Name, new NullableAttribute())
它工作正常,我得到了属性类的确切实例。
但是,我不喜欢我必须使用新的NullableAttribute()作为参数,我想调用如下:
cc.GetPropertyAttribute<NullableAttribute>(x => x.Name)
但是这不起作用,因为只要我删除第二个参数并在方法名称中添加1个泛型类型,它就开始需要其他两个。有没有办法强制该方法推断3个通用参数中的2个?即我想指定属性类,但不想指定类名和属性名。
更新:
这是已实现的代码,感谢Jon,以及字符串解决方案的代码。我已经决定嵌套这个类,这样如果我为其他扩展类引入相同的方法,我就不会对命名空间进行轮询。
public static class AttributeExtensions
{
public static ObjectProperty<T, TProperty> From<T, TProperty>(this T instance, Expression<Func<T, TProperty>> propertySelector)
{
return new ObjectProperty<T, TProperty>(instance, propertySelector);
}
public class ObjectProperty<T, TProperty>
{
private readonly T instance;
private readonly Expression<Func<T, TProperty>> propertySelector;
public ObjectProperty(T instance, Expression<Func<T, TProperty>> propertySelector)
{
this.instance = instance;
this.propertySelector = propertySelector;
}
public U GetAttribute<U>() where U : Attribute
{
return Attribute.GetCustomAttribute(instance.GetType().GetProperty((propertySelector.Body as MemberExpression).Member.Name), typeof(U), true) as U;
}
}
public static T GetPropertyAttribute<T>(this object instance, string propertyName) where T : Attribute
{
return Attribute.GetCustomAttribute(instance.GetType().GetProperty(propertyName), typeof(T), true) as T;
}
}
现在调用就像这样:
var cc = new CustomClass();
var attr = cc.From(x => x.Name).GetAttribute<NullableAttribute>();
答案 0 :(得分:8)
有没有办法强制该方法推断3个通用参数中的2个?
一种常见的方法是使用具有这两个类型参数的中间类型,然后在该类型中使用通用方法以允许您提供最后一个:
public static AttributeFetcher<T, TProperty> FetchFrom<T, TProperty>
(this T instance, Expression<Func<T, TProperty>> propertySelector)
{
return new AttributeFetcher<T, TProperty>(instance, propertySelector);
}
public class AttributeFetcher<T, TProperty>
{
private readonly T instance;
private readonly Expression<Func<T, TProperty>> propertySelector;
// Add obvious constructor
public U Attribute<U>() where U : Attribute
{
// Code as before
}
}
然后你可以写:
cc.FetchFrom(x => x.Name).Attribute<NullableAttribte>();
考虑到你真的只需要AttributeFetcher
,我可能实际上可以使PropertyInfo
非通用。上面的代码适用于更一般的情况。