C#4.0。我有一个带有属性的慢属性。我想在不调用getter的情况下读取此属性:
[Range(0.0f, 1000.0f)]
public float X
{
get
{
return SlowFunctionX();
}
}
这就是我现在所拥有的:
public static T GetRangeMin<T>(T value)
{
var attribute = value.GetType()
.GetField(value.ToString())
.GetCustomAttributes(typeof(RangeAttribute), false)
.SingleOrDefault() as RangeAttribute;
return (T)attribute.Minimum;
}
var min = GetRangeMin<double>(X); // Will call the getter of X :(
问:如何在不调用X
的getter的情况下阅读此属性?
答案 0 :(得分:9)
要读取属性上的属性,只需直接加载属性
var attrib = typeof(TheTypeContainingX)
.GetProperty("X")
.GetCustomAttributes(typeof(RangeAttribute), false)
.Cast<RangeAttribute>()
.FirstOrDefault();
return attrib.Minimum;
答案 1 :(得分:1)
无论如何你都无法得到它,因为你会调用类似GetRangeMin<float>(0.0f)
的东西,而float类型没有一个名为whatever-value-X-has的字段。 / p>
如果您希望以通用且类型安全的方式执行此操作,则需要使用表达式:
public static T GetRangeMin<T>(Expression<Func<T>> value)
这样调用:
var min = GetRangeMin(() => X);
然后,您需要导航表达式树以获取属性信息
MemberExpression memberExpression = value.Body as MemberExpression;
if (null == memberExpression || memberExpression.Member.MemberType != MemberTypes.Property)
throw new ArgumentException("Expect a field access", "FieldExpression");
PropertyInfo propInfo = (PropertyInfo)memberExpression.Member;
现在您可以在GetCustomAttributes
上propInfo
了。另外,如果您担心继承,可能需要使用Attribute.GetCustomAttributes(propInfo, ...)
,因为即使您要求,propInfo.GetCustomAttributes(...)
也不会遍历继承树。