Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中以正确的方式删除特权枚举标志#_C#_.net_Wpf_Enums - Fatal编程技术网

C# 在C中以正确的方式删除特权枚举标志#

C# 在C中以正确的方式删除特权枚举标志#,c#,.net,wpf,enums,C#,.net,Wpf,Enums,我有一个用户权限的枚举类型,如下所示: [Flags] public enum UserPrivileges : byte { None = 0, // 0000 0000 View = 1 << 0, // 0000 0001 Import = 1 << 1,

我有一个用户权限的枚举类型,如下所示:

[Flags]
public enum UserPrivileges : byte
{
    None = 0,                                     // 0000 0000
    View = 1 << 0,                                // 0000 0001
    Import = 1 << 1,                              // 0000 0010
    Export = 1 << 2,                              // 0000 0100
    Supervisor = View | Import | Export | 1 << 3, // 0000 1111
    Admin = Supervisor | 1 << 4                   // 0001 1111
}
0001 1111 // Admin
0000 0111 // 7 flag
---------
0000 0111 // Remain only where 7 bit was set.
这对于在GUI中向用户显示和添加权限非常有效。它还可用于删除Superflag,如Supervisor(所有标志
=
Supervisor都被删除,其他标志不变)

问题是,当我取消选中导入时,例如,我想删除所有超级标记(主管、管理员),但希望保留其他标记(查看、导出)


但我还没有想出一个好主意来实现这一点。任何一个对此有好办法的男孩?

如果我知道你想要什么,这应该可以解决问题

    byte tmp = 1 << 3 | 1 << 4;
    byte removeSuperFlagMask = (byte) (~tmp);

    byte notSuperflagsMask = 1 << 3 | 1 << 2 | 1 << 1;
    if ((valueToRemove & notSuperflagsMask) != 0)
    {
        newValue = (byte)(removeSuperFlagMask & currentValue & ~valueToRemove);
    }

byte tmp=1如果我理解正确,您希望删除
Supervisor
Admin
,因此:

UserPrivileges newPrivileges = (UserPrivileges)(((byte)currentPrivileges) & 7;
它将执行如下操作:

[Flags]
public enum UserPrivileges : byte
{
    None = 0,                                     // 0000 0000
    View = 1 << 0,                                // 0000 0001
    Import = 1 << 1,                              // 0000 0010
    Export = 1 << 2,                              // 0000 0100
    Supervisor = View | Import | Export | 1 << 3, // 0000 1111
    Admin = Supervisor | 1 << 4                   // 0001 1111
}
0001 1111 // Admin
0000 0111 // 7 flag
---------
0000 0111 // Remain only where 7 bit was set.
另一个例子

0000 0011 // View | Import
0000 0111 // 7 flag
---------
0000 0011 // Remain only where 7 bit was set.
“保留”的意思是,如果设置了
7
标志,它将在结果中保留该值(beein
0
1
)。当
7
标志为
0
时,它将杀死
0

的值,使我走上正确的道路,但它对我来说不够通用,因此我想出了另一个解决方案:

    public object ConvertBack(object value, Type targetType,
                              object parameter, CultureInfo culture)
    {
        var mask = (byte)parameter;

        if ((bool)value)
        {
            _targetValue |= mask;
        }
        else
        {
            if (IsSuperFlag(mask) && mask != 1)
                _targetValue &= (byte)(mask >> 1);
            else
            {
                // Get all flags from enum type that are no SuperFlags
                var flags = Enum.GetValues(targetType).Cast<Enum>();
                flags = flags.Where(x => !IsSuperFlag(System.Convert.ToByte(x)));

                long nonSuperFlags = 0;

                foreach (var flag in flags)
                {
                    nonSuperFlags |= System.Convert.ToByte(flag);
                }

                // Now only remove everything except the nonSuperFlags
                // and then remove the mask
                _targetValue &= (byte)(~(_targetValue ^ nonSuperFlags | mask));

            }
        }

        return Enum.Parse(targetType, _targetValue.ToString());
    }

    private bool IsSuperFlag(byte flag)
    {
        var b = flag;
        b--;
        b |= (byte)(b >> 1);
        b |= (byte)(b >> 2);
        b |= (byte)(b >> 4);
        b |= (byte)(b >> 8);

        return b == flag;
    }
public object ConvertBack(对象值,类型targetType,
对象参数,CultureInfo(区域性)
{
变量掩码=(字节)参数;
如果((布尔)值)
{
_targetValue |=掩码;
}
其他的
{
如果(IsSuperFlag(掩码)&掩码!=1)
_targetValue&=(字节)(掩码>>1);
其他的
{
//从枚举类型中获取所有没有超标记的标记
var flags=Enum.GetValues(targetType.Cast();
flags=flags.Where(x=>!IsSuperFlag(System.Convert.ToByte(x));
长非超级标志=0;
foreach(标志中的var标志)
{
非超级标志|=System.Convert.ToByte(标志);
}
//现在只删除除非超级标志之外的所有内容
//然后取下面具
_targetValue&=(字节)(~(_targetValue^非超级标志|掩码));
}
}
返回Enum.Parse(targetType,_targetValue.ToString());
}
专用布尔IsSuperFlag(字节标志)
{
var b=标志;
b--;
b |=(字节)(b>>1);
b |=(字节)(b>>2);
b |=(字节)(b>>4);
b |=(字节)(b>>8);
返回b==标志;
}

我只是得到了枚举类型的所有非超级标记,它们只删除了超级标记,然后删除了标志。

您是否试图避免使用条件逻辑?如果您开始使用If/else语句对其进行编码,这很简单。在您的示例中-您喜欢删除
Admin
Import
?嗯,您在这里滥用枚举,这给您带来了所有的麻烦。@Staeff:是的,但这里的问题是您试图将逻辑编码到枚举中。我想,这个问题与enum的定义有关,它将权限(查看、导入、导出)与角色(主管、管理员)混合在一起。谢谢你让我想到这个想法,但我需要一个更通用的解决方案。看看我的答案。这远远不是最好的办法。但既然你完成了你的目标,那就是问题所在。