【问题标题】:Custom Enum Type自定义枚举类型
【发布时间】:2011-09-11 20:57:05
【问题描述】:

我有一个基于标志的枚举,虽然它目前没有超过 64 值(长)的界限,但它可能会。

我使用枚举来描述 MEF 插件/组件适用于我们的哪些客户。这将是我们实现客户定制的主要机制。

我很确定我的老板不会对我们只能为 64 个客户提供服务的想法感到太高兴,但如果没有 Enum,我就无法实施如此灵活的系统。

理想情况下,我想写:

[Flags]
public enum Organisations : MyBinaryFormat
{
    // Customers
    CustomerA = 1 << 0,
    CustomerB = 1 << 1,
    CustomerC = 1 << 2,
    CustomerD = 1 << 3,

    // Special
    Any                 = CustomerA | CustomerB | CustomerC,
    HostedCustomers     = CustomerA | CustomerC,
}

这是定义我的元数据的一种非常方便的语法,不幸的是,黑客类型并不是我的强项,所以我已经尽我所能围绕这个主题进行研究/实验,但没有取得太多成果:

  • This 问题说可以使用带有枚举的 BitArray 类,这将是理想的但是没有提供实现。

  • 我看到 VS2008 文档中使用的 TypeDef 被传递到枚举 here。在示例中,它只是简单地掩盖了bool 类型,看起来好像这个关键字已被删除。

  • 我已经搜索了多个 msdn“枚举”页面(我不愿意说“全部”,但为了自己的利益,我看到的太多了)。但是this page 表示要考虑使用 System.Int32 作为数据类型,除非枚举是标志枚举,并且您有超过 32 个标志。

  • 但是,每当我尝试使用自定义类型。 我没有看到任何东西(除了我的例外)明确说您不能使用自己的自定义数据类型,但我也没有找到它的单一实现。

我想明确知道是否可以在自定义类型上构建枚举

【问题讨论】:

    标签: c# visual-studio-2010 c#-4.0 language-features


    【解决方案1】:

    将它们表示为代表客户 ID 的唯一字符串(或数字)数组不是更好吗?

    例如,您可以定义如下元数据接口:

    public interface ICustomerValidityMetadata
    {
        string[] ValidCustomers { get; }
    }
    

    您可以将其滚动到元数据属性中:

    [MetadataAttribute]
    public class ExportForCustomerAttribute : ExportAttribute, ICustomerValidityMetadata
    {
        public ExportForCustomerAttribute(Type type, params string[] customerIds)
            : base(type)
        {
            ValidCustomers = customerIds ?? new string[0];
        }
    }
    

    然后您可以申请为:

    [ExportForCustomer(typeof(IModule), "CustomerA", "CustomerB")]
    public class SomeModule : IModule { }
    

    然后你可以过滤:

    var modules = container.GetExports<IModule, ICustomerValidityMetadata>()
        .Where(l => l.Metadata.ValidCustomers.Contains("CustomerA");
    

    但是,老实说,可变实体的硬编码表示是一个坏主意,您应该从数据库或配置等中动态地进行查找。这样您只需要导出一些表示模块 ID 的元数据,然后您可以查找特定客户以查看它是否可用。

    希望对您有所帮助。

    【讨论】:

    • 我倾向于同意你的观点,特别是关于将这些信息存储在配置中。但是元数据无法动态加载(根据我今天阅读的一些帖子,无法检查 atm)。 MEF 有链接失败的习惯,所以我热衷于避免弱类型配置,因为在测试过程中很容易遗漏一个小错字,你也失去了能够以强类型方式对组织进行分组的便利。如果无法在枚举下使用自定义类型,我可能会使用与此类似的实现。谢谢。
    【解决方案2】:

    定义一个包含 CustomerID 列表甚至只是 List&lt;int&gt;CustomerList 类有什么问题? .NET API 有许多列表操作方法,它们允许您将客户 ID 列表进行 OR 组合,就像您对标志枚举所做的那样。

    例如

    List<int> hostedCustomers = new List<int>{1,4, 5};
    List<int> newCustomers = new List<int>{6,4,7};
    List<int> newHostedCustomers = hostedCustomers.Union(newCustomers).ToList();
    

    【讨论】:

    • 我试图避免弱类型配置,所以我可能会使用(非标志)客户枚举。为了方便语法,我什至可以重载运算符以提供联合功能。我的主要反对意见是它还不存在,而我的枚举在一段时间内可以作为Int64 使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 2016-07-17
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    相关资源
    最近更新 更多