1

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 :(

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

4

2 回答 2

9

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

var attrib = typeof(TheTypeContainingX)
  .GetProperty("X")
  .GetCustomAttributes(typeof(RangeAttribute), false)
  .Cast<RangeAttribute>()
  .FirstOrDefault();
return attrib.Minimum;
于 2013-03-25T17:03:06.577 回答
1

无论如何,您将无法获得它,因为您将调用类似的东西GetRangeMin<float>(0.0f),而浮点类型没有名为whatever-value-X-has 的字段。

如果您想以通用且类型安全的方式执行此操作,则需要使用表达式:

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(...)即使您要求它也不会遍历继承树。

于 2013-03-25T17:06:15.143 回答