简体   繁体   中英

C# - How to use enum flags in a certain way

What I am I trying to do is this:

[Flags]
public enum Actions
{
    Action1 = 0x01,
    Action2 = 0x02,
    Action3 = 0x04
}

The object has the actions flag set to 7 to begin with. The object can then perform any of the actions available. But here is the kicker. The object can perform the actions in this combination:

-Action 1, Action 2, Action 3

-Action 1, Action 1, Action 3

-Action 1, Action 1, Action 2

-Action 1, Action 1, Action 1

So, actions 2 and 3 can only be used once, while action 1 can be used, upto, three times. If Action 2 or Action 3 is used, then Action 1 can only be used twice. Is this the best way to go about this? Or should I try to create a new object that will let me handle this? I would like to use enums to do this, but I can't, for the life of me, figure out how to do this or find anything on the web regarding something like this.

Thank you, in advance, for any help that can be provided.

The enums only point to a single action. If you have a combination of actions, I can suggest a collection to organize them.

Example:

List<Actions> _actionCombos = new List<Actions>(3);

_actionsCombos.Add(Action.Action1);
_actionsCombos.Add(Action.Action1);
_actionsCombos.Add(Action.Action1);

This would be the combination for all the 1s. It sounds like there is a another variable that determines the action combinations. So, you could build logic in for that value to return the proper action combination (if it exists).

I would like to use enums to do this, but I can't...

You can certainly use an enumerated type to define a constant for each action, but you'll need to implement some logic in order to enforce your rules. The enumerated type cannot do that alone. You can create a class used to manage these actions that uses the enumerated value to determine the type as a first step, but it will need to maintain some state in order to determine whether or not a given action is valid at a given time.

With enum flags you cannot combine (OR) the same value twice and so you cannot perform the kind of validation you're looking for. You will have to create a class or use a collection and apply your rules logic. Since you have to do this anyway you don't have to worry about a Flags attribute. It will not be useful to you. Not in this case anyway.

But, if your cases are limited to the four examples that you list then you could have an enum with four values that represents one of each of the cases. Bit flagging would still not be useful here but you would have some rules enforcement via an enum.

I enuded doing this to get it to work how I wanted.

I still need to go through and refactor, but it works so far for my need:

public Actions Actions{get; set;}

public bool UseAction(Actions action)
        {
            bool mReturn = false;

            if (action == Actions.Action2)
            {
                if ((this.Actions & Actions.Action2) == Actions.Action2)
                {
                    mReturn = true;
                    this.Actions = this.Actions & ~action;
                }
                else if ((this.Actions & Actions.Action3) == Actions.Action3)
                {
                    mReturn = true;
                    this.Actions = this.Actions & ~Actions.Action3;
                }
                else
                {
                    mReturn = false;
                }
            }
            else if (action == Actions.Action3)
            {
                if ((this.Actions & Actions.Action3) == Actions.Action3)
                {
                    mReturn = true;
                    this.Actions = this.Actions & ~action;
                }
            }
            else
            {
                if ((this.Actions & Actions.Action1) == Actions.Action1)
                {
                    mReturn = true;
                    this.Actions = this.Actions & ~action;
                }
                else if ((this.Actions & Actions.Action3) == Actions.Action3)
                {
                    mReturn = true;
                    this.Actions = this.Actions & ~Actions.Action3;
                }
                else if ((this.Actions & Actions.Action2) == Actions.Action2)
                {
                    mReturn = true;
                    this.Actions = this.Actions & ~Actions.Action2;
                }
            }

            return mReturn;
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM