Search code examples
c#flags

"Decimal" flags (instead of binary) - built-in way?


I have this formula which I got from some documentation, which is supposed to explain what a "Flags" integer represents:

Flags = Spectator * 1 + TemporarySpectator * 10 + PureSpectator * 100 + AutoTarget * 1000 + CurrentTargetId * 10000

I wrote this code which is able to convert a number (flags) to some booleans + one integer, just like in the formula:

////////// From Values to Flag //////////

bool Spectator          = true;
bool TemporarySpectator = false;
bool PureSpectator      = true;
bool AutoTarget         = false;
int  CurrentTargetId    = 255;

int Calculate() =>
    (Convert.ToInt32(Spectator)          * 1) +
    (Convert.ToInt32(TemporarySpectator) * 10) +
    (Convert.ToInt32(PureSpectator)      * 100) +
    (Convert.ToInt32(AutoTarget)         * 1000) +
    (Convert.ToInt32(CurrentTargetId)    * 10000);

int Result = Calculate(); // 2550101


////////// From Flag to Values //////////

CurrentTargetId      = Convert.ToInt32(Result / 10000);
AutoTarget           = Convert.ToBoolean((Result - (CurrentTargetId * 10000)) / 1000);
PureSpectator        = Convert.ToBoolean((Result - (CurrentTargetId * 10000) - (Convert.ToInt32(AutoTarget) * 1000)) / 100);
TemporarySpectator   = Convert.ToBoolean((Result - (CurrentTargetId * 10000) - (Convert.ToInt32(AutoTarget) * 1000) - (Convert.ToInt32(PureSpectator) * 100)) / 10);
Spectator            = Convert.ToBoolean((Result - (CurrentTargetId * 10000) - (Convert.ToInt32(AutoTarget) * 1000) - (Convert.ToInt32(PureSpectator) * 100) - (Convert.ToInt32(TemporarySpectator) * 100)) / 1);

Result = Calculate(); // 2550101

As you can see, my code is also able to do the reverse operation too - which is converting values to a flag.

Fiddle of my code: https://dotnetfiddle.net/ua2wi8

Does this kind of operation have any name? I know about the FlagsAttribute for enums which is similar but stores flags as individual bits ("binary digits") instead of decimal digits like in my case.

Is there any easier or even native way to do this in C#? Using booleans right from a model class would be a plus.


Solution

  • Here is how I ended up doing it, with manual string parsing:

    public class SpectatorStatus : IFlag
    {
        public SpectatorStatus(int value)
        {
            var valueStr = value.ToString("D7");
    
            const char True = '1';
    
            CurrentTargetId = Convert.ToInt32(valueStr[..3]);
            AutoTarget = valueStr[3] == True;
            PureSpectator = valueStr[4] == True;
            TemporarySpectator = valueStr[5] == True;
            Spectator = valueStr[6] == True;
        }
    
        public bool Spectator { get; }
        public bool TemporarySpectator { get; }
        public bool PureSpectator { get; }
        public bool AutoTarget { get; }
        public int CurrentTargetId { get; }
    
        public override string ToString()
            => (Convert.ToInt32(Spectator)
                + Convert.ToInt32(TemporarySpectator) * 10
                + Convert.ToInt32(PureSpectator) * 100
                + Convert.ToInt32(AutoTarget) * 1000
                + CurrentTargetId * 10000)
                .ToString("D7");
    }