Битовая манипуляция uint32 bitfields в C#

У меня есть два перечисления в C#

public class PlayerAttributes 
{

        private UInt32 m_AttributeFlagsMask;
        private UInt32 m_AttributeFlagsBitmap;

        [Flags]
        public enum EAttributesFlagsBmp
        {
           AIn = 0,
           BIn = (1 << 1),  //1
           CIn = (1 << 2),  //2
           DIn = (1 << 3),  //4 
           EIn = (1 << 4), //8
           FIn = (1 << 5),  //16
           GIn = (1 << 6)  //32
        }

        [Flags]
        public enum EAttributeFlagsMask
        {
            None = 0,
            AIn = (1 << 1),     //1
            BIn = (1 << 2),  //2
            CIn = (1 << 3),   //4
            DIn = (1 << 4),  //8
            EIn = (1 << 5),  //16
            FIn = (1 << 6)  //32
        }

        public UInt32 AttributeFlagsMask { get { return m_AttributeFlagsMask; } private set { m_AttributeFlagsMask = value; } }
        public UInt32 AttributeFlagsBmp { get { return m_AttributeFlagsBmp; } private set { m_AttributeFlagsBmp = value; } }

        public bool SetAInAndBIn(bool a_in, bool b_in)
        {
            if(a_in && !b_in)
            {
                   UInt32 flag = ((UInt32)PlayerAttributes.EAttributesFlagsBmp.AIn | ~(UInt32)PlayerAttributes.EAttributesFlagsBmp.BIn);

            }else if(bin && !a_in)
            {
                   UInt32 flag = (~(UInt32)PlayerAttributes.EAttributesFlagsBmp.AIn | (UInt32)PlayerAttributes.EAttributesFlagsBmp.BIn);

            }
            AttributeFlagsBmp  = flag  

            return true;
        }
}

Приведенный выше код, кажется, не правильно устанавливает значение.
What I want is in

case 1 AIn должен быть установлен и BInдолжен быть снят. (Все остальные биты должны быть неизменными)

и
In case 2 BInдолжен быть установлен и AInдолжен быть снят. (Все остальные биты должны быть неизменными)

как этого достичь

Метки

1 ответ

  1. Не уверен, если это то, что вы хотите, но если следующая строка

    ((UInt32)PlayerAttributes.EAttributesFlagsBmp.AIn | ~(UInt32)PlayerAttributes.EAttributesFlagsBmp.BIn)
    

    ожидается, чтобы установить A и unset B, не изменяя другие, это не будет работать (это будет фактически перевернуть все другие). Чтобы установить A и снять B без изменения чего-либо еще, следует использовать:

    ((UInt32)PlayerAttributes.EAttributesFlagsBmp.AIn & ~(UInt32)PlayerAttributes.EAttributesFlagsBmp.BIn)
    

    Так же, как и в обычных булевых, при отрицании одной стороны необходимо изменить или И (и наоборот) в сравнении, чтобы сохранить то же самое поведение.

    РЕДАКТИРОВАТЬ:

    Причина, по которой другие флаги стираются при установке, заключается в том, что вы устанавливаете только эти 2 флага в свойстве, а затем перезаписываете все, что существует в свойстве, путем установки значения на нем. Чтобы просто изменить значения, которые уже находятся в свойстве, необходимо использовать соответствующий оператор на его значениях, а затем установить его обратно. Вроде этого:

    AttributeFlagsBitmap = AttributeFlagsBitmap |
        (UInt32)PlayerAttributes.EAttributesFlagsBmp.AIn &
        ~(UInt32)PlayerAttributes.EAttributesFlagsBmp.BIn;