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
我有一个带有布尔值的自定义属性。我想 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