基于属性对枚举执行 LINQ 操作

发布于 2025-01-09 09:01:13 字数 1673 浏览 1 评论 0原文

我正在尝试根据每个枚举选项的属性查询我的枚举。

我知道如何获取列表。通过此代码,这非常简单:

            var list = Enum.GetValues(typeof(FamilyNameOptions))
                    .Cast<FamilyNameOptions>()
                    .Select(v => v.ToString())
                    .ToList();

如果这是我的枚举设置,我如何查询值为 TRUE 的属性 DrawingListIsEnabled

    public enum FamilyNameOptions
    {
        [DrawingListIsEnabled(true)]
        [FamilyUserName("FamilyName1")]
        FamilyName1= 0,

        [DrawingListIsEnabled(false)]
        [FamilyUserName("FamilyName2")]
        FamilyName2= 1,
    }


    /// <summary>
    /// DrawingListIsEnabledAttribute
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.All)]
    public class DrawingListIsEnabledAttribute : Attribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingListIsEnabledAttribute"/> class.
        /// </summary>
        /// <param name="isEnabled">if set to <c>true</c> [is enabled].</param>
        public DrawingListIsEnabledAttribute(bool isEnabled)
        {
            this.IsEnabled = isEnabled;
        }

        /// <summary>
        /// Gets a value indicating whether this instance is enabled.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is enabled; otherwise, <c>false</c>.
        /// </value>
        public bool IsEnabled { get; private set; }
    }

预期结果将是一个列表1:

姓氏1

I'm trying to query against my Enum based on an attribute on each enum option.

I know how to get the list. That is pretty simple via this code:

            var list = Enum.GetValues(typeof(FamilyNameOptions))
                    .Cast<FamilyNameOptions>()
                    .Select(v => v.ToString())
                    .ToList();

If this is my Enum setup, how can I query against the attribute DrawingListIsEnabled where the value is TRUE

    public enum FamilyNameOptions
    {
        [DrawingListIsEnabled(true)]
        [FamilyUserName("FamilyName1")]
        FamilyName1= 0,

        [DrawingListIsEnabled(false)]
        [FamilyUserName("FamilyName2")]
        FamilyName2= 1,
    }


    /// <summary>
    /// DrawingListIsEnabledAttribute
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.All)]
    public class DrawingListIsEnabledAttribute : Attribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingListIsEnabledAttribute"/> class.
        /// </summary>
        /// <param name="isEnabled">if set to <c>true</c> [is enabled].</param>
        public DrawingListIsEnabledAttribute(bool isEnabled)
        {
            this.IsEnabled = isEnabled;
        }

        /// <summary>
        /// Gets a value indicating whether this instance is enabled.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is enabled; otherwise, <c>false</c>.
        /// </value>
        public bool IsEnabled { get; private set; }
    }

The expected result would be a list of 1:

FamilyName1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花开半夏魅人心 2025-01-16 09:01:13

您需要使用反射来查找静态字段列表,而不是使用 Enum.GetValues

typeof(FamilyNameOptions)
    .GetFields(BindingFlags.Static | BindingFlags.Public)
    // For definition order, rather than value order;
    .OrderBy(f => f.MetadataToken)
    .Select(f => new {
        Value = (FamilyNameOptions)f.GetValue(null),
        Text = f.Name,
        Enabled = f.GetCustomAttribute<DrawingListIsEnabledAttribute>()?.IsEnabled ?? false,
        FamilyName = f.GetCustomAttribute<FamilyUserNameAttribute>()?.Name
    })

由于这些信息在运行时都不会更改,因此您可能希望创建一个辅助类型来缓存结果。

Rather than using Enum.GetValues you will need to use reflection to find the static field list;

typeof(FamilyNameOptions)
    .GetFields(BindingFlags.Static | BindingFlags.Public)
    // For definition order, rather than value order;
    .OrderBy(f => f.MetadataToken)
    .Select(f => new {
        Value = (FamilyNameOptions)f.GetValue(null),
        Text = f.Name,
        Enabled = f.GetCustomAttribute<DrawingListIsEnabledAttribute>()?.IsEnabled ?? false,
        FamilyName = f.GetCustomAttribute<FamilyUserNameAttribute>()?.Name
    })

Since none of that information will change at runtime, you might wish to create a helper type to cache the results.

勿忘心安 2025-01-16 09:01:13

下面是完成此任务的简单 LINQ 查询:

var items = Enum.GetValues<FamilyNameOptions>()
                .Select(item => item.GetType().GetMember(item.ToString()).FirstOrDefault())
                .Where(memberInfo => memberInfo?.GetCustomAttribute<DrawingListIsEnabledAttribute>().IsEnabled ?? false)
                .Select(enabledMemberInfo => enabledMemberInfo.GetCustomAttribute<FamilyUserNameAttribute>().FamilyUserName);

注意,您不需要原始的列表。另外,我使用的是 Enum.GetValues 的通用版本,这消除了您的版本中对 Cast 的需要。

为了自我记录,我保留了 LINQ 名称很长时间;请随意使用典型的较短名称。该代码的工作原理如下:

  • Enum.GetValues 返回 enum FamilyNameOptions 成员的强类型列表。
  • 第一个 .Select 语句获取描述枚举成员(以及所有自定义属性)的 MemberInfo 对象,
  • 接下来,.Where 根据 < code>DrawingListIsEnabledAttribute 的 IsEnabled 属性
  • 最后,最后一个 .SelectFamilyUserNameAttribute 中获取名称FamilyUserName 属性(我想这就是它的名字 - 如果不是,请相应地更改它)。

Here's a simple LINQ query to accomplish this task:

var items = Enum.GetValues<FamilyNameOptions>()
                .Select(item => item.GetType().GetMember(item.ToString()).FirstOrDefault())
                .Where(memberInfo => memberInfo?.GetCustomAttribute<DrawingListIsEnabledAttribute>().IsEnabled ?? false)
                .Select(enabledMemberInfo => enabledMemberInfo.GetCustomAttribute<FamilyUserNameAttribute>().FamilyUserName);

Note, you don't need your original list. Also, I'm using the generic version of Enum.GetValues<TEnum>, which eliminates the need for Cast in your version.

I kept my LINQ names long in effort to be self-documenting; feel free to go with the typical shorter names. The code works as follows:

  • Enum.GetValues<FamilyNameOptions> returns a strongly-typed list of members of enum FamilyNameOptions.
  • first .Select statement gets the MemberInfo objects describing the enum members (along with all custom attributes)
  • next, .Where filters the results based on DrawingListIsEnabledAttribute's IsEnabled property
  • finally, the last .Select grabs the names from the FamilyUserNameAttribute's FamilyUserName property (I presume that's what it's called - change it accordingly if not).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文