在 C# 中扩展枚举

2024-02-26

在java中,我习惯于扩展枚举值或重写方法,如下所示:

    enum SomeEnum
    {

        option1("sv")
        {
            public String toString()
            {
                return "Some value";
            }     
        }, 
        option2;

        private String PassedValue;

        public SomeEnum(String somevalue)
        {
            this.PassedValue = somevalue;
        }

        public SomeEnum()
        {
                this.PassedValue = "Default Value";
        }

        public String getPassedValue()
        {
            return this.PassedValue;
        }

    }

有没有办法在 C# 中做类似的事情,或者枚举在 C# 中受到更多限制


我希望枚举在 .Net 中更加强大。我喜欢.Net!您可以使用属性来完成同样的事情。下面的代码只需编写一次即可在任何地方使用。这将是一个很长的答案,但我认为这是一个很好的解决方案,所以要有耐心!

Usage

SomeEnum e = SomeEnum.ValueTwo;
string description = e.GetDescription();

The Enum

使用属性来描述枚举及其值。

[DescriptiveEnumEnforcement(DescriptiveEnumEnforcement.EnforcementTypeEnum.ThrowException)]
public enum SomeEnum
{
    [Description("Value One")]
    ValueOne,

    [Description("Value Two")]
    ValueTwo,

    [Description("Value 3")]
    ValueThree
}

描述属性

/// <summary>Indicates that an enum value has a description.</summary>
[AttributeUsage(AttributeTargets.Field)]
public class DescriptionAttribute : System.Attribute
{
    /// <summary>The description for the enum value.</summary>
    public string Description { get; set; }

    /// <summary>Constructs a new DescriptionAttribute.</summary>
    public DescriptionAttribute() { }

    /// <summary>Constructs a new DescriptionAttribute.</summary>
    /// <param name="description">The initial value of the Description property.</param>
    public DescriptionAttribute(string description)
    {
        this.Description = description;
    }

    /// <summary>Returns the Description property.</summary>
    /// <returns>The Description property.</returns>
    public override string ToString()
    {
        return this.Description;
    }
}

描述性枚举执行属性

确保枚举配置正确的属性。

/// <summary>Indicates whether or not an enum must have a NameAttribute and a DescriptionAttribute.</summary>
[AttributeUsage(AttributeTargets.Enum)]
public class DescriptiveEnumEnforcementAttribute : System.Attribute
{
    /// <summary>Defines the different types of enforcement for DescriptiveEnums.</summary>
    public enum EnforcementTypeEnum
    {
        /// <summary>Indicates that the enum must have a NameAttribute and a DescriptionAttribute.</summary>
        ThrowException,

        /// <summary>Indicates that the enum does not have a NameAttribute and a DescriptionAttribute, the value will be used instead.</summary>
        DefaultToValue
    }

    /// <summary>The enforcement type for this DescriptiveEnumEnforcementAttribute.</summary>
    public EnforcementTypeEnum EnforcementType { get; set; }

    /// <summary>Constructs a new DescriptiveEnumEnforcementAttribute.</summary>
    public DescriptiveEnumEnforcementAttribute()
    {
        this.EnforcementType = EnforcementTypeEnum.DefaultToValue;
    }

    /// <summary>Constructs a new DescriptiveEnumEnforcementAttribute.</summary>
    /// <param name="enforcementType">The initial value of the EnforcementType property.</param>
    public DescriptiveEnumEnforcementAttribute(EnforcementTypeEnum enforcementType)
    {
        this.EnforcementType = enforcementType;
    }
}

获取描述

/// <summary>Provides functionality to enhance enumerations.</summary>
public static partial class EnumUtil
{
    /// <summary>Returns the description of the specified enum.</summary>
    /// <param name="value">The value of the enum for which to return the description.</param>
    /// <returns>A description of the enum, or the enum name if no description exists.</returns>
    public static string GetDescription(this Enum value)
    {
        return GetEnumDescription(value);
    }

    /// <summary>Returns the description of the specified enum.</summary>
    /// <param name="value">The value of the enum for which to return the description.</param>
    /// <returns>A description of the enum, or the enum name if no description exists.</returns>
    public static string GetDescription<T>(object value)
    {
        return GetEnumDescription(value);
    }

    /// <summary>Returns the description of the specified enum.</summary>
    /// <param name="value">The value of the enum for which to return the description.</param>
    /// <returns>A description of the enum, or the enum name if no description exists.</returns>
    public static string GetEnumDescription(object value)
    {
        if (value == null)
        return null;

        Type type = value.GetType();

        //Make sure the object is an enum.
        if (!type.IsEnum)
            throw new ApplicationException("Value parameter must be an enum.");

        FieldInfo fieldInfo = type.GetField(value.ToString());
        object[] descriptionAttributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

        //If no DescriptionAttribute exists for this enum value, check the DescriptiveEnumEnforcementAttribute and decide how to proceed.
        if (descriptionAttributes == null || descriptionAttributes.Length == 0)
        {
            object[] enforcementAttributes = fieldInfo.GetCustomAttributes(typeof(DescriptiveEnumEnforcementAttribute), false);

            //If a DescriptiveEnumEnforcementAttribute exists, either throw an exception or return the name of the enum instead.
            if (enforcementAttributes != null && enforcementAttributes.Length == 1)
            {
                DescriptiveEnumEnforcementAttribute enforcementAttribute = (DescriptiveEnumEnforcementAttribute)enforcementAttributes[0];

                if (enforcementAttribute.EnforcementType == DescriptiveEnumEnforcementAttribute.EnforcementTypeEnum.ThrowException)
                    throw new ApplicationException("No Description attributes exist in enforced enum of type '" + type.Name + "', value '" + value.ToString() + "'.");

                return GetEnumName(value);
            }
            else //Just return the name of the enum.
                return GetEnumName(value);
        }
        else if (descriptionAttributes.Length > 1)
            throw new ApplicationException("Too many Description attributes exist in enum of type '" + type.Name + "', value '" + value.ToString() + "'.");

        //Return the value of the DescriptionAttribute.
        return descriptionAttributes[0].ToString();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中扩展枚举 的相关文章

随机推荐

  • 中止 Linux 上的阻塞读取

    我在线程中运行的 Linux 中有一个阻塞读取 在程序关闭期间 我想使线程脱离此读取 不幸的是 我无法使用轮询或选择并编写正确的代码 因为读取的文件是不实现轮询 选择功能的设备驱动程序 作为临时解决方案 我当前通过 pthread kill
  • 将 Access 2010 转换为旧版本

    我希望能够使用脚本将 Access 2010 数据库转换为多个不同的旧版本 因此 如果我将 2010 Access 提供给脚本 我希望它输出以下版本之一 2000 2002 2003 或 2007 这怎么可能 我不是在寻找完整的脚本 而是在
  • gvim:轻松复制到系统剪贴板

    我在 Ubuntu 10 10 上使用 gVim 我想将文本复制 猛拉 到系统剪贴板 以便复制的文本可在其他应用程序中使用 这适用于 y 但我想让它与y 我尝试过绘制地图y to y但是之后yy不再工作 因为它产生 y y 我也尝试过 se
  • 可选类型注释。检查是否为 None 后使用值?

    我正在用 python 编写一些带有类型注释的代码 我对可选类型有疑问 例如对于这样的代码 maybe number Optional int definition if maybe number None else I know its
  • 如何重写 Java 中的类方法并向其添加“抛出”声明?

    Android 中是否有可能有一个 抛出 东西的 AsyncTask 如果我不 Override 该方法 则不会调用它 如果我在末尾添加 抛出 则会出现编译器错误 例如 我想做类似的事情 class testThrows extends A
  • 下载 SQL SERVER 代理 - Microsoft SQL Server

    我已下载 SQL SERVER MANAGEMENT STUDIO 但未找到 SQL SERVER AGENT 我应该单独安装吗 谁能告诉我免费软件 SQL SERVER AGENT 的下载链接吗 如果使用 SQL Server Manag
  • 在 C# 中以编程方式创建 Azure AD

    是否可以在 Azure 订阅中以编程方式创建 Azure Active Directory 我查看了 Azure 管理 API 可以看到创建 VM 数据库的方法 但没有看到 WAAD 的方法 如果可能 每个订阅可以创建多少个 WAAD 不可
  • ISerialized 是否向后兼容具有较少字段的类的早期版本?

    抱歉 如果我的问题措辞有点奇怪 基本上 我有一个可序列化的类 目前只有一个字段 但随着我们向系统添加功能 将来肯定会获得更多 序列化过程将用于将实例传递到 WCF 服务 以及从文件读取实例或将实例写入文件 当然 如果我不断用额外的字段更新类
  • 优化 C++ 模板执行

    我正在从事性能至关重要的项目 该应用程序正在处理大量数据 代码是用C 编写的 我需要做一些更改 给出了以下代码 这不是我的代码 我将其简化为最小 void process
  • HAML如何识别块的结尾?

    form for subject url gt action gt create do f render partial gt form locals gt f gt f form buttons submit tag Create Sub
  • Neo4j 使用属性过滤器通过多个关系定向路径

    作为 Cypher 和 Neo4j 的新手 我在为我的用例构建查询时遇到问题 我正在构建一个简单的 ACL 访问控制列表 并正在寻找一条通过权限关系向上层次结构的路径 一张图或许能更好地解释它 Key Users gt Blue Group
  • C# 源生成器应该刷新/删除发出的文件

    我创建了一个源生成器来扩展满足某些条件的 部分 类 为了检查和查看生成的代码 我通过将以下内容添加到我的项目中来启用这些文件的发射
  • 如何使用 Spring Data ElasticSearch 为 POJO 定义 ElasticSearch 索引字段名称

    我正在使用 Spring Data ElasticSearch 来执行 CRUD 操作 默认情况下 当使用 Document 注释的 POJO 写入 ElasticSearch 索引时 索引字段名称与 POJO 的 Java 属性名称相同
  • WPF:如何冻结数据网格中的列标题

    如何将我的列标题冻结在DataGrid in my WPF窗口 以便当我向下滚动时 标题仍然可见 Edit 这是我的XAML
  • Scrapy 将子站点项目与站点项目合并

    我试图从子网站中抓取详细信息并与网站中抓取的详细信息合并 我一直在通过 stackoverflow 以及文档进行研究 但是 我仍然无法让我的代码工作 看来我从子网站提取附加详细信息的功能不起作用 如果有人能看一下我将非常感激 coding
  • 测试元素的类型 python tuple/list

    如何验证列表或元组中所有元素的类型是否相同并且属于某种类型 例如 1 2 3 test for all int True 1 3 a test for all int False all isinstance n int for n in
  • 日期输入的 onchange [重复]

    这个问题在这里已经有答案了 可能的重复 当 的值发生更改时 会触发哪些事件 https stackoverflow com questions 3940258 what events does an input type number fi
  • 从 grails 项目执行甘特脚本

    我已经编写了自己的甘特脚本 它可以在命令行中正常工作 现在我需要从 grails 项目运行这个脚本 如下所示 def outputMessage try GroovyScriptEngine engine new GroovyScriptE
  • 如何使用 TFS REST API 获取迭代剩余天数

    我目前正在使用REST API version 2 0并连接到我的 TFS 实例PowerShell 我可以得到以下信息 迭代ID迭代名称队员团队成员每天的容量 使用下面的示例 GET https instance DefaultColle
  • 在 C# 中扩展枚举

    在java中 我习惯于扩展枚举值或重写方法 如下所示 enum SomeEnum option1 sv public String toString return Some value option2 private String Pass