且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C#确保有效的枚举值 - 面向未来的方法

更新时间:2023-11-23 11:27:16

在这种情况下,我会尽量不使用枚举,而是一个类的公共静态只读域这是该类的实例。看看.NET Framework并不是对颜色的例子。有一类的颜色,你可以使用对象,如Color.Black,Color.Blue,等他们不是常数,而是提供了几乎所有同样的好处。再加上他们有一个常数,没有其他好处。见C#3版语言规范也谈到了这一点。

In such a case I would try not to use an enum but rather a class with public static readonly fields which are instances of the class. See what the .Net framework does with colors for example. There is a class Color and you can use objects like Color.Black, Color.Blue, etc. They're not constants but offer almost all the same benefits. Plus they have other benefits that constants don't have. See the C# version 3 language specification which also talks about this a bit.

不过这个想法是,你没有一个case语句。你每一个枚举的成员,该方法(DoSomething的或其他)能正确地对待它补充足够的其他属性。当其他开发人员要添加其他成员对象,他需要提供所需要的属性。我的例子:我需要一个枚举,为不同的动作,用户可以在系统中。要检查这些行动所需的权限,登录等等。我还需要父母和孩子的动作(重命名的东西是它的编辑等。部分),用于过滤的目的分组行动起来抽象的行动,并专项行动所有和无(无是不确定的)。每一个需要在数据库中的ID和文本为好。我想它还是工作,如果someody发明了一种新型的行动。我所做的是这样的(大量的code省略只是给你的想法):

But the idea is that you don't have a case statement. You add enough other properties to each "enum" member that the method (DoSomething or whatever) can treat it properly. When another developer wants to add another member object, he needs to supply the attributes needed. My example: I needed an "enum" for the different actions a user can take in the system. These actions needed to be checked for permissions, logged, etc. I also needed parent and child actions (renaming something is "part of" editing it, etc.), abstract actions used for grouping actions together for filtering purposes, and special actions "All" and "None" (None being undefined). Each one needed an ID and text in the database as well. I wanted it to still work if someody invented a new type of action. What I did is something like this (lots of code omitted just to give you the idea):

  public class Action
  {
    protected Action(bool Abstract, Action Parent, int ID, string Name, bool Undefined)
    { /* snip */ }
    protected Action(bool Abstract, Action Parent, int ID, string Name)
      : this(Abstract, Parent, ID, Name, false)
    { }
    //----------------------------------------------------------------------------------------
    public static readonly Action All = new Action(true, null, 0, "All");
    public static readonly Action None = new Action(false, All, 6, "(Undefined)", true);
    public static readonly Action Modifying = new Action(true, All, 1, "Modifying");
    public static readonly Action Creating = new Action(false, Modifying, 2, "Creating");
    public static readonly Action Deleting = new Action(false, Modifying, 3, "Deleting");
    public static readonly Action Editing = new Action(false, Modifying, 4, "Editing");
    public static readonly Action Exporting = new Action(false, All, 5, "Exporting");
    public static readonly Action Renaming = new Action(false, Editing, 7, "Renaming");
    /* snip */
    //----------------------------------------------------------------------------------------
    /* template for new entries:
    public static readonly Action  = new Action(false, All, , "");
    */
  }

有更多的动作。并有一些在上操作操作其他类的方法。他们都保持只要每个动作提供所需的信息工作。显影剂添加操作被强制提供的信息。如果当前的属性是不够的一些未来特殊的行动,那么更多的属性将不得不在以后添加。注意,构造被保护,所以仅类本身可以创建操作。我在检查重复的ID和姓名以及很多其他事情的主要构造省略了大量的code。现在,您可以使用这样的:

There are more actions. And there are a number of methods in other classes that operate on actions. They all keep working as long as each action provides the information needed. The developer adding an action is forced to provide the information. If the current attributes are not enough for some future "special" action then more attributes will have to be added later. Note that the constructors are protected, so only the class itself can create actions. I omitted a lot of code in the main constructor that checks for duplicate IDs and Names and lots of other things. You can now use it like this:

Log.LogAction(Action.Renaming);

该方法LogAction没有在这一个case语句。它使用了动作的属性

The method LogAction doesn't have a case statement in it. It uses the attributes of the action.

你是什么枚举?

问候