检索 属性 的名称和值具有特定的属性值

Retrieve name and value of property has a specific attribute value

假设有一个属性,例如:

public class ValueAttribute : Attribute
{
  public int Val;
  public ValueAttribute(int val)
  {
    Val = val;
  }
}

并应用于class:

public class Person
{
  [Value(10)]
  public string FirstName;
  [Value(20)]
  public string LastName;
  [Value(30)]
  public string Age;
}

我将如何有效地检索具有 Value(20) 的 属性 第一次出现的 PropertyInfo(最好没有 loop/iteration)?

您可以使用下面的代码

var attr = (ValueAttribute)(typeof(Person)
          .GetField("FirstName")
          .GetCustomAttributes(false)
          .GetValue(0));
Console.WriteLine(attr.Val);  

首先,您有字段而不是属性,因此如果有的话,您需要从 FieldInfo 对象中获取属性。其次,如果没有某种形式的迭代,就没有办法做你想做的事。如果您担心每次都必须查找它,您可以缓存每种类型的结果。

public static class ValueHelper<T>
{
     private static readonly Dictionary<int, FieldInfo> FieldsByValue;

     static ValueHelper()
     {
         FieldsByValue = typeof(T)
                 .GetFields()
                 .Select(f => new { 
                       Field = f, 
                       Att = f.GetCustomAttribute<ValueAttribute>() 
                  })
                 .Where(c => c.Att != null)
                 .GroupBy(c => c.Att.Val, (val, flds) => new { 
                      Value = val, 
                      Field = flds.First() 
                  })
                 .ToDictionary(c => c.Value, c => c.Field);
     }

     public static FieldInfo GetFieldByValue(int value)
     {
          if (FieldsByValue.TryGetValue(value, out var field)) 
             return field;
          // not found, return null...
          // throw exception, etc
          return null;
     } 

} 

这可以像这样使用:

var field = ValueHelper<Person>.GetFieldByValue(20);

反射只发生一次(多亏了静态构造函数),然后被缓存在查找中 table 以供进一步访问。

如果你真的有属性,那么用PropertyInfo替换FieldInfo,用GetProperties替换GetFields

注意:我不确定反射返回的fields/properties的顺序是否保证。它们可能按源顺序返回,但这很可能是 实现细节