【问题标题】:Read Attribute on property without calling getter?在不调用 getter 的情况下读取属性上的属性?
【发布时间】:2023-04-06 16:19:01
【问题描述】:

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

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

【问题讨论】:

标签: c# custom-attributes


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    无论如何你都无法得到它,因为你会调用类似GetRangeMin&lt;float&gt;(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;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 2019-03-14
      • 2014-12-04
      • 1970-01-01
      • 2012-10-16
      • 2016-09-08
      相关资源
      最近更新 更多