2011-06-09 147 views
0

我有一个基于标志的枚举,虽然它目前不超过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传入enum here。在这个例子中,它只是掩盖了bool类型,而且看起来好像关键字已被删除。

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

  • 然而,有一个例外,我不断收到 “ERROR1:类型字节,为sbyte,短,USHORT,INT,UINT,长或ulong预期” 每当我试图使用自定义类型。 我没有看到任何东西(除了我的例外),它明确表示你不能使用自己的自定义数据类型,但我也没有找到它的一个单一的实现。

我想明确地知道,如果在一个自定义类型构造一个枚举可能

回答

3

有什么不对的定义CustomerList类,其中包含CustomerIDs的列表,甚至只是List<int>? .NET API有许多List操作方法,这些方法将允许您将客户ID列表组合在一起,就像您使用标志枚举一样。

例如

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(); 
+0

我试图避免弱类型的配置,所以我可能会使用(非标志)客户枚举。为了方便的语法,我甚至可以重载运算符来提供联合功能。我的主要反对意见是它还不存在,而我的枚举在一段时间内可以像Int64一样好。 – 2011-06-09 17:56:38

1

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

E.克,你可以定义的元数据接口,如:

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的元数据,即然后您可以查找特定客户以查看它是否可用。

希望有所帮助。

+0

我倾向于同意你的看法,特别是关于将这些信息存储在配置中。但元数据不能动态加载(根据我今天看到的一些帖子,无法检查atm)。 MEF有一个链接失败的习惯,所以我很乐意避免使用弱类型的配置,因为在测试过程中可能很容易漏掉一个小的错字,也会失去以强类型方式对组织进行分组的便利。如果不可能在枚举下使用自定义类型,我可能会使用类似于此的实现。谢谢。 – 2011-06-09 17:43:38