基于布尔值更改标志

本文关键字:标志 于布尔 | 更新日期: 2023-09-27 18:04:32

有没有更优雅的方法?

[Flags]
public enum SomeFlaggedEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 4
}

private SomeFlaggedEnum _myFlags;
public bool EnabledValue1
{
    set 
    {
        if (value)
        {
            _myFlags |= SomeFlaggedEnum.Value1;
        }
        else
        {
            _myFlags &= ~SomeFlaggedEnum.Value1;
        }
    }
} 

我知道可能有一个简单的答案,我只是想得太多了…

编辑:在其中一个答案中指出枚举是不正确的。

基于布尔值更改标志

我的意思是,你可以这样:

_myFlags = value ? myFlags | SomeFlaggedEnum.Value1 : myFlags & ~SomeFlaggedEnum.Value1;

但我认为你的解决方案很好。

你可以使用条件语句:

_myFlags = value ? _myFlags | SomeFlaggedEnum.Value1
                 : _myFlags & ~SomeFlaggedEnum.Value1;

如果你为每个flag设置一个属性,假设你有超过3个flag,看起来会很难看。使用一个方法,你可以指定要设置哪些标志,这不是更容易吗?

public void EnableFlag(SomeFlaggedEnum value, bool set) {
    _myFlags = set ? value | _myFlags : ~value & _myFlags;
}

EnableFlag(SomeFlaggedEnum.Value1, true);

为标志创建一个泛型setter(在Enum类中已经有一个泛型的"HasFlag",但是像这样的扩展将对它进行补充)。

public static class EnumExtensions
{
    public static T SetFlags<T>(this T value, T flags, bool on) where T : struct
    {    
        long lValue = Convert.ToInt64(value);
        long lFlag = Convert.ToInt64(flags);
        if (on)
        {
            lValue |= lFlag;
        }
        else
        {
            lValue &= (~lFlag);
        }
        return (T)Enum.ToObject(typeof(T), lValue);
    }
}

一旦你有了这个,你可以为每个标志创建属性(但很快就会变得混乱),或者简单地将获取和设置标志委托给HasFlag/SetFlag

你的setter很好。

问题是使用FlagsAttribute不会使编译器为使用枚举成员作为标志选择有用的值。SomeFlaggedEnum.Value1为零,因为它是枚举中的第一个声明值,所以它根本不代表位标志。

[Flags]
public enum SomeFlaggedEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 4
}