在不调用getter的情况下读取属性的属性?

时间:2013-03-25 17:01:11

标签: c# custom-attributes

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的情况下阅读此属性?

2 个答案:

答案 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;

现在您可以在GetCustomAttributespropInfo了。另外,如果您担心继承,可能需要使用Attribute.GetCustomAttributes(propInfo, ...),因为即使您要求,propInfo.GetCustomAttributes(...)也不会遍历继承树。