gpt4 book ai didi

c# - 在 C# 中使用位掩码

转载 作者:IT王子 更新时间:2023-10-29 03:37:39 27 4
gpt4 key购买 nike

假设我有以下内容

int susan = 2; //0010
int bob = 4; //0100
int karen = 8; //1000

然后我将 10 (8 + 2) 作为参数传递给一个方法,我想将其解码为 susan 和 karen

我知道10是1010

但是我怎样才能做一些逻辑来查看是否检查了特定位

if (condition_for_karen) // How to quickly check whether effective karen bit is 1

现在我能想到的就是检查我传递的数字是否是

14 // 1110
12 // 1100
10 // 1010
8 // 1000

当我在现实世界场景中有更多的实际位时,这似乎不切实际,使用掩码来检查我是否满足仅 karen 的条件的更好方法是什么?

我可以考虑向左移动然后向后移动然后向右移动然后向后移动以清除我感兴趣的位以外的位,但这似乎也过于复杂。

最佳答案

执行此操作的传统方法是在 enum 上使用 Flags 属性:

[Flags]
public enum Names
{
None = 0,
Susan = 1,
Bob = 2,
Karen = 4
}

然后您将按如下方式检查特定名称:

Names names = Names.Susan | Names.Bob;

// evaluates to true
bool susanIsIncluded = (names & Names.Susan) != Names.None;

// evaluates to false
bool karenIsIncluded = (names & Names.Karen) != Names.None;

逻辑按位组合可能很难记住,所以我使用 FlagsHelper 类让自己的生活更轻松*:

// The casts to object in the below code are an unfortunate necessity due to
// C#'s restriction against a where T : Enum constraint. (There are ways around
// this, but they're outside the scope of this simple illustration.)
public static class FlagsHelper
{
public static bool IsSet<T>(T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;

return (flagsValue & flagValue) != 0;
}

public static void Set<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;

flags = (T)(object)(flagsValue | flagValue);
}

public static void Unset<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;

flags = (T)(object)(flagsValue & (~flagValue));
}
}

这将允许我将上面的代码重写为:

Names names = Names.Susan | Names.Bob;

bool susanIsIncluded = FlagsHelper.IsSet(names, Names.Susan);

bool karenIsIncluded = FlagsHelper.IsSet(names, Names.Karen);

请注意,我还可以通过这样做将 Karen 添加到集合中:

FlagsHelper.Set(ref names, Names.Karen);

我可以用类似的方式删除 Susan:

FlagsHelper.Unset(ref names, Names.Susan);

*正如 Porges 指出的那样,.NET 4.0 中已经存在与上述 IsSet 方法等效的方法:Enum.HasFlag .不过,SetUnset 方法似乎没有等效项;所以我还是要说这门课有一些优点。


注意:使用枚举只是解决此问题的常规方法。您完全可以将上述所有代码转换为使用 int,它也能正常工作。

关于c# - 在 C# 中使用位掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3261451/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com