读取属性上的属性而不调用getter

本文关键字:属性 调用 getter 读取 | 更新日期: 2023-09-27 18:05:52

c# 4.0。我有一个带有属性的slow属性。我想在不调用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 :(

Q:如何在不调用X的getter的情况下读取此属性?

读取属性上的属性而不调用getter

要读取属性上的属性,只需直接加载属性

var attrib = typeof(TheTypeContainingX)
  .GetProperty("X")
  .GetCustomAttributes(typeof(RangeAttribute), false)
  .Cast<RangeAttribute>()
  .FirstOrDefault();
return attrib.Minimum;

无论如何你都无法获得它,因为你将调用GetRangeMin<float>(0.0f)之类的东西,并且float类型没有名为whatever-value-X-has的字段。

如果你想以一种通用的和类型安全的方式来做,你需要使用Expressions:

public static T GetRangeMin<T>(Expression<Func<T>> value)

调用:

var min = GetRangeMin(() => X);

然后需要导航表达式树以获取属性info

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;

现在你可以在propInfoGetCustomAttributes。顺便说一句,如果您担心继承问题,可能需要使用Attribute.GetCustomAttributes(propInfo, ...),因为即使您要求propInfo.GetCustomAttributes(...)遍历继承树,它也不会遍历。