自定义枚举类型

发布于 2024-11-14 20:50:29 字数 1432 浏览 2 评论 0原文

我有一个基于 Flag 的枚举,虽然它目前没有超过 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,
}

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

  • 这个问题说这是可以将 BitArray 类与枚举一起使用,这将是理想的选择,但是没有提供实现。

  • 我已经看到 VS2008 文档中使用的 TypeDef 传递到枚举 此处。在示例中,它只是屏蔽了 bool 类型,看起来好像这个关键字已被删除。

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

  • 但是,有一个例外,每当我尝试使用自定义类型时,我都会收到“Error1:类型为 byte、sbyte、short、ushort、int、uint、long 或 ulong 预期”。 我没有看到任何内容(除了我的例外)明确表示您不能使用自己的自定义数据类型,但我也没有找到它的单个实现。

我想确切地知道是否可以在自定义类型上构造枚举

I have a Flag based enum, and while it doesn't currently exceed the bounds of 64 value (long), it potentially will.

I'm using the enum to describe which of our customers an MEF plugin/component is meant for. This will be our main mechanism for implementing customer customisations.

I'm fairly certain my bosses won't be too pleased with the idea that we can only serve 64 customers, but I cannot implement such a flexible system without an Enum.

Ideally, I'd like to write:

[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 is a very convenient syntax for defining my metadata, unfortunately hacking types isn't really my forte so I've tried my best to research/experiment around the topic but haven't come to much:

  • This question says it's possible to use the BitArray class with an enumeration, which would be ideal However there isn't an implementation provided.

  • I've seen a TypeDef used in VS2008 documentation passed into an enum here. In the example it simply masks the bool type, and it looks as though this keyword was removed.

  • I've searched multiple msdn "enum" pages (I'm reluctant to say 'all' but I've seen far too many for my own good). However this page says to consider using System.Int32 as the data type unless the enumeration is a flags enum, and you have more than 32 flags.

  • However, there is an exception I keep getting "Error1: Type byte, sbyte, short, ushort, int, uint, long, or ulong expected" whenever I try to use a custom type.
    I haven't seen anything (besides my exception) which expressly says you cannot use your own custom data type, but I also haven't found a single implementation of it.

I'd like to know definitively if constructing an enum on a custom type is possible

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

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

发布评论

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

评论(2

翻了热茶 2024-11-21 20:50:29

定义包含 CustomerID 列表甚至仅包含 ListCustomerList 类有什么问题? .NET API 有许多列表操作方法,允许您将客户 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();

What is wrong with defining a CustomerList class which contains a list of CustomerIDs or even just List<int>? The .NET API has numerous List manipulation methods that will allow you to OR together lists of customer IDs just as you have done with your flags enum.

e.g.

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();
海之角 2024-11-21 20:50:29

将它们表示为代表客户 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 的元数据,然后您可以针对特定客户进行查找以查看它是否可用。

希望有帮助。

Would it not be better to express them as an array of unique strings (or numbers) that represent the customer Id?

E.g, you could define a metadata interface like:

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

Which you could roll into a metadata attribute:

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

Which you could then apply as:

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

And you can then filter:

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

But, to be honest, hard coding representations of changeable entities is a bad idea, you should really do a lookup dynamically, either from a database, or config, etc. That way you need only export some metadata representing the module Id, which you can then lookup against a specific customer to see if it is useable.

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文