检索 属性 的名称和值具有特定的属性值
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的顺序是否保证。它们可能按源顺序返回,但这很可能是 实现细节 。
假设有一个属性,例如:
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的顺序是否保证。它们可能按源顺序返回,但这很可能是 实现细节 。