C# return [说明] 属性基于对自定义属性的过滤

C# return [Description] attribute based on filtering on a custom attribute

我有一个带有布尔值的自定义属性。我想 return [Description] 仅用于自定义值为 true 的枚举值。

样本:

    [Description("Concept Set Model")]
    [ModelIsDesignTimeDefinable(true)]
    ConceptSet = 1 << 24

我有这两个扩展方法,但它们显然不正确,因为它们需要协同工作:

public static IEnumerable<string> ExtractDescriptionAttrib(this IEnumerable<string> set, Type type) => set
    .Select(n => type.GetMember(n).First())
    .SelectMany(member => member
        .GetCustomAttributes(typeof(DescriptionAttribute), true)
        .Cast<DescriptionAttribute>())
    .Select(x => x.Description);

public static IEnumerable<bool> ExtractDefinableAttrib(this IEnumerable<string> set, Type type) => set
    .Select(n => type.GetMember(n).First())
    .SelectMany(member => member
        .GetCustomAttributes(typeof(ModelIsDesignTimeDefinableAttribute), true)
        .Cast<ModelIsDesignTimeDefinableAttribute>())
    .Select(x => x.Definable);

我原来的调用代码:

public static IEnumerable<string> GetModelDescriptions()
{
    var type = typeof(ModelType);
    var set = Enum.GetValues(type)
        .Cast<ModelType>()
        .Where(x => x > 0)
        .Select(x => x.ToString());

    // return with " Model" clipped off the end
    return set
        .ExtractDescriptionAttrib(type)
        .Select(x => x[0..^6]);
}

我确定解决方案很简单,但我想念它。

我想出了一些可行的方法,但它需要一个更好的名称,您可能需要根据自己的称呼方式对其进行调整。

public static IEnumerable<string> GetDescriptions<TEnum, TCustomAttribute>(
    Func<TCustomAttribute, bool> predicate)
    where TEnum : System.Enum
    where TCustomAttribute : Attribute
{
    return typeof(TEnum)
        .GetFields(BindingFlags.Static | BindingFlags.Public)
        .Where(x =>
        {
            var descriptionAttr = x.GetCustomAttribute<DescriptionAttribute>(true);
            var customAttr = x.GetCustomAttribute<TCustomAttribute>(true);

            return x.DeclaringType == typeof(TEnum)
                && descriptionAttr != null
                && customAttr != null
                && predicate(customAttr);
        })
        .Select(x => x.GetCustomAttribute<DescriptionAttribute>().Description);
}

像这样定义枚举:

public enum Test
{
    [Description("Concept Set Model")]
    [ModelIsDesignTimeDefinable(true)]
    ConceptSet = 1,
    [Description("Concept Set Model 2")]
    [ModelIsDesignTimeDefinable(false)]
    ConceptSet2 = 2,
    [Description("Concept Set Model 3")]
    ConceptSet3 = 4,
}

并调用它:

var descriptions = GetDescriptions<Test, ModelIsDesignTimeDefinableAttribute>(x => x.Definable == true);

foreach (var item in descriptions)
{
    Console.WriteLine(item);
}

产生:

Concept Set Model