2

私は次の宣言を持っています

 private uint mask;
 Action<FlagEnum> setField = new Action<FlagEnum>(x => this.mask = (uint)x);

たとえば、次の列挙型:

[Flags]
public enum FlagEnum : uint
{
    Clear = 0x0,
    F1 = 0x1,
    F2 = F1 << 1,
    F3 = F2 << 1,
    F4 = F3 << 1,
    F5 = F4 << 1,
    F6 = F5 << 1
}

ここで、「クリア」フラグを除くすべてのフラグを設定したいと考えています。私はこれを試しました:

 setField(!FlagEnum.Clear);

しかし、私は次のメッセージを受け取ります

Operator '!' cannot be applied to perand of type 'BitMask.FlagEnum'

たとえば、次のようにフラグを設定します。

 setField(FlagEnum.F1)

正常に動作します。

だから問題は、私のアプローチで「クリア」フィールドの代わりにFlagEnumのすべてのフィールドを設定するにはどうすればよいですか? または、これは不可能であり、この要件を実装する必要があります。

4

2 に答える 2

4

あなたの特定のケースでFlagEnum.Clearは、ゼロに設定されています。つまり、「設定」することはできません。フラグは次のように定義されます (8 ビットに短縮):

Clear = 00000000
F1    = 00000001
F2    = 00000010
F3    = 00000100
F4    = 00001000
F5    = 00010000
F6    = 00100000

したがって、たとえば、F2F3F5組み合わされた場合、値のバイナリ表現は次のようになります00010110。これは、これら 3 つのフラグのビットごとの OR から取得された組み合わせです。

しかし、Clearそこにどのように追加されることになっていますか?Clearはゼロであるため、値を OR しても何も変わりません。代わりに、他のフラグが設定されていない場合にのみ、値は自動的に になりますClear

これが意図したものでない場合は、 への割り当て0x01から始めますClear


一般に、フラグ変数から単一の値を実際に削除できます。フラグの値を否定するというあなたの考えは正しかった - C# では、ビット単位の NOT は、論理否定に~使用される感嘆符ではなくチルダ () で表されます。 .

したがって、 の反転ビット パターンはF2です11111101F2から削除する00010110には、結果が になるため、OR は実行できません11111111。代わりに、否定された値を前のフラグの組み合わせと AND する必要があります。

00010110 & 11111101 = 00010100 (F3, F5)
于 2013-02-11T08:25:44.050 に答える
0

OR Mapper アプローチに従って、私はそのように解決しました:

/// <summary>
    /// Operates the specified flag.
    /// </summary>
    /// <param name="flag">The flag.</param>
    /// <param name="operation">The operation.</param>
    public void Operate(FlagEnum flag, OperationEnum operation)
    {
        this.flag = flag;
        switch (operation)
        {
            case OperationEnum.AND:
                operate((x, y) => x & y);
                break;
            case OperationEnum.OR:
                operate((x, y) => x | y);
                break;
            case OperationEnum.XOR:
                operate((x, y) => x ^ y);
                break;
            case OperationEnum.NOT:
                throw new NotImplementedException("The operation 'NOT' is not implemented so far!");
        }
    }

 /// <summary>
    /// Operates the specified operation.
    /// </summary>
    /// <param name="operation">The operation.</param>
    private void operate(Func<uint, uint, uint> operation)
    {
        this.Mask = operation(this.Mask, (uint)this.flag);
    }

    /// <summary>
    /// Clears the mask.
    /// </summary>
    public void ClearMask()
    {
        this.Mask = (uint)FlagEnum.Clear;
    }
于 2013-02-11T14:05:57.473 に答える