[英]How to get a list of enum members that have been decorated with specific attribute
我想返回具有特定属性的枚举成员列表。 所以对于代码示例,我想要一个包含枚举 SecondValue 和 ThirdValue 的列表,但不是 FirstValue 或 FourthValue,因为它没有属性 Container。
我怎么能这样做?
PS:这之前被标记为重复,并带有指向此的链接: Getting attributes of Enum's value
这不是同一个问题。 我制作了更多示例代码以使我的问题更清楚。 请参阅 function 定义及其应返回的内容。
[AttributeUsage(AttributeTargets.Field)]
public sealed class ContainerAttribute : Attribute
{
public string Name { get; }
public ContainerAttribute(string name)
{
Name = name;
}
}
public enum MyEnum
{
[SomeOtherAttribute("attr")]
FirstValue,
[Container("name1")]
SecondValue,
[Container("name1")]
ThirdValue,
FourthValue
}
public List<MyEnum> GetEnumsWithAttribute(Attribute value) { }
public void Main(String[] args) {
// someEnums should return list with content: [MyEnum.SecondValue, MyEnum.ThirdValue];
var someEnums = GetEnumsWithAttribute(ContainerAttribute);
}
每当您使用属性时,您都必须使用反射。 混合一些 Linq,您可以检查枚举的字段以按属性类型过滤,然后从字段名称解析结果。
Type ta = typeof(ContainerAttribute);
Type t = typeof(MyEnum);
var result = t.GetFields()
.Where(a => a.CustomAttributes.Any(c => c.AttributeType == ta))
.Select(a => (MyEnum)Enum.Parse(t, a.Name))
.ToList();
更新
虽然您的问题尚不清楚您是否需要按Name
进一步过滤,但 Guru 的回答暗示您可能会这样做,或者将来会这样做。 如果是这样,您可以通过更改Where
子句以接受您想要的Name
的字符串来编辑我的解决方案:
// method would take a string argument rather than hard-coding "name1"
.Where(a => a.CustomAttributes.Any(c => c.AttributeType == ta && c.ConstructorArguments.Any(ca => ca.Value.ToString() == "name1")))
您可以为此使用反射:
public static List<MyEnum> GetEnumsWithAttribute(Attribute value)
{
return typeof(MyEnum)
.GetMembers()
.Where(m => m.MemberType == MemberTypes.Field)
.Where(m => m.GetCustomAttributes().Any(a => a.Equals(value)))
.Select(m => Enum.Parse<MyEnum>(m.Name))
.ToList();
}
此实现依赖于.Equals
在ContainerAttribute
中被重载,如下所示:
public override bool Equals(object? obj)
{
var other = obj as ContainerAttribute;
if (other == null) return false;
return this.Name == other.Name;
}
如果您不想覆盖Equals
您可以将您的方法更改为通用:
public static List<MyEnum> GetEnumsWithAttribute<T>(T value, Func<T, T , bool> comparerFunc) where T: Attribute
{
return typeof(MyEnum)
.GetMembers()
.Where(m => m.MemberType == MemberTypes.Field)
.Where(m => m.GetCustomAttributes().Any(a => a is T && comparerFunc((T)a, value)))
.Select(m => Enum.Parse<MyEnum>(m.Name))
.ToList();
}
和用法:
var someEnums = GetEnumsWithAttribute(new ContainerAttribute("name1"), (a1, a2) => a1.Name == a2.Name);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.