C#中的枚举子集或子组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/518442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 06:29:31  来源:igfitidea点击:

Enum subset or subgroup in C#

c#enums

提问by srmark

I have an existing enum with numerous items in it.

我有一个现有的枚举,其中包含许多项目。

I also have existing code which does certain things with this enum.

我也有使用这个枚举做某些事情的现有代码。

I would now like a way to view only a subset enum members. What I'm looking for is a way to divide my enum into groups. I need to preserve the (int) value of each member and I need to preserve the ability to view all enum members if needed.

我现在想要一种仅查看子集枚举成员的方法。我正在寻找的是一种将我的枚举分组的方法。我需要保留每个成员的 (int) 值,并且如果需要,我需要保留查看所有枚举成员的能力。

The only thing I can think of is to just create a new enum for each subenum that only contain the items I want using the same name and value.

我唯一能想到的就是为每个子枚举创建一个新的枚举,这些子枚举只包含我想要使用相同名称和值的项目。

This works but violates the whole no repetition principle.

这有效但违反了整体不重复原则。

I don't expect anyone to have a better alternative but I thought I'd ask just in case someone had a fancy trick to show me.

我不希望有人有更好的选择,但我想我会问,以防万一有人向我展示一个奇特的技巧。

Thanks, as always.

谢谢,一如既往。

采纳答案by srmark

In the end, I had to rewrite much of the code but the following "trick" was derived:

最后,我不得不重写大部分代码,但得出了以下“技巧”:

I trashed C# enums and use static members on a regular class. This class was made into a singleton and is inited on application start.

我丢弃了 C# 枚举并在常规类上使用静态成员。此类被制成单例并在应用程序启动时初始化。

My static members' constructors are allowed to reference another static member as a "parent".

我的静态成员的构造函数可以引用另一个静态成员作为“父”。

Next, my init method uses reflection to go through each static member and indexes them based on several properties. These indexes are stored in hashtables which are also members of the singleton.

接下来,我的 init 方法使用反射来遍历每个静态成员并根据几个属性对它们进行索引。这些索引存储在哈希表中,哈希表也是单例的成员。

I thus get:

我因此得到:

a singleton object which:

一个单例对象,它:

  • has static members which can be easily accessed during design time.
  • can be used during run-time to lookup certain static members (based on "group" and other properties).
  • 具有可以在设计时轻松访问的静态成员。
  • 可在运行时用于查找某些静态成员(基于“组”和其他属性)。

My init method does a fair amount of validation. If invalid (such as duplicate) static members are built, you get a run-time error on application startup.

我的 init 方法做了大量的验证。如果构建了无效(例如重复)静态成员,则会在应用程序启动时收到运行时错误。

Obviously a pretty big hack but I'm quite happy with it.

显然是一个相当大的黑客,但我很高兴。

回答by Jeff Yates

You could define the values using an enumeration but then reference them via constants in static classes so that your developers don't get over-faced by the large enum. You could have:

您可以使用枚举定义值,然后通过静态类中的常量引用它们,这样您的开发人员就不会被大型枚举所困扰。你可以有:

enum MySuperEnumGroup
{
  Group1Item1,
  Group1Item2,
  Group1Item3,

  Group2Item1,
  Group2Item2,
  Group2Item3,

  Group3Item1,
  Group3Item2,
  Group3Item3,
}

static class MySuperEnumGroup_Group1
{
  public const MySuperEnumGroup Item1 = MySuperEnumGroup.Group1Item1;
  public const MySuperEnumGroup Item2 = MySuperEnumGroup.Group1Item2;
  public const MySuperEnumGroup Item3 = MySuperEnumGroup.Group1Item3;
}

static class MySuperEnumGroup_Group2
{
  public const MySuperEnumGroup Item1 = MySuperEnumGroup.Group2Item1;
  public const MySuperEnumGroup Item2 = MySuperEnumGroup.Group2Item2;
  public const MySuperEnumGroup Item3 = MySuperEnumGroup.Group2Item3;
}

//etc.

回答by olli-MSFT

This might help: Fake Enums in C#

这可能会有所帮助:C# 中的 Fake Enums

回答by ed_hubbell

I would go with this (which works in VB.NET at least)

我会选择这个(至少在 VB.NET 中有效)

enum MySuperEnumGroup 
{ 
  Group1Item1, 
  Group1Item2, 
  Group1Item3, 

  Group2Item1, 
  Group2Item2, 
  Group2Item3, 

  Group3Item1, 
  Group3Item2, 
  Group3Item3, 
} 

enum MySubEnumGroup 
{
Group2Item1 = MySuperEnumGroup.Group2Item1 
Group3Item1 = MySuperEnumGroup.Group3Item1 
Group3Item3 = MySuperEnumGroup.Group3Item3
}

Then do some kind of CType when you need to.

然后在需要时执行某种 CType。

回答by Mathieu Guindon

If the enums don't have explicit values, give them one and use flags to define the "groupings":

如果枚举没有明确的值,给它们一个并使用标志来定义“分组”:

[Flags]
enum MySuperEnumGroup
{
    Group1 = 1 << 0,
    Group2 = 1 << 1,
    Group3 = 1 << 2,

    Group1Item1 = 1 << 10 | Group1,
    Group1Item2 = 1 << 11 | Group1,
    Group1Item3 = 1 << 12 | Group1,

    Group2Item1 = 1 << 13 | Group2,
    Group2Item2 = 1 << 14 | Group2,
    Group2Item3 = 1 << 15 | Group2,

    Group3Item1 = 1 << 16 | Group3,
    Group3Item2 = 1 << 17 | Group3,
    Group3Item3 = 1 << 18 | Group3,
}

Then you can use Enum.GetValuesand HasFlagto get the values for a given "grouping":

然后您可以使用Enum.GetValuesHasFlag获取给定“分组”的值:

var group1 = Enum.GetValues(typeof(MySuperEnumGroup))
                 .Cast<MySuperEnumGroup>()
                 .Where(value => value.HasFlag(MySuperEnumGroup.Group1))
                 .ToArray();