检查一组位标志是否至少包含其他位标志的一个标志

Check if set of bitflags include atleast one flag of other bitflags

我正在编写一个事件系统,其中每个侦听器都会侦听一个、多个或所有通道(GameEventChannel 枚举),并且只能为一个、多个或所有通道(GameEventChannels)引发事件。我现在拥有的是。

[System.Flags]
public enum GameEventChannel {
    One = 1,
    Two = 2,
    Three = 4,
    Four = 8,
    Five = 16,
    Six = 32,
    Seven = 64,
    Eight = 128,
    Nine = 256,
    Ten = 512
}

事件被另一个 class 调用,后者调用 Invoke(GameEventChannel channel) 。 在 Invoke 函数中,我遍历此事件的所有监听器,并想确定它应该调用哪些监听器

public void Invoke(GameEventChannel channels)
    {
        Debug.Log("Invoke with channales: " + channels.ToString());
        for (var i = 0; i < _Listeners.Count; i++)
        {
            var listener = _Listeners[i];
            if (listener != null && IsListeningToChannel())
            {
                _Listeners[i]?.OnEventInvoked();
            }
        }
    }

我需要编写函数 IsListeningToChannel() ,它需要确定监听器是否正在监听事件要调用的 GameEventChannel。

例如

Event.Invoke(GameEventChannel.One | GameEventChannel.Two | GameEventChannel.Three)

Listener1 正在收听 "GameEventChannel.Two | GameEventChannel.Eight"

我如何检查是否应该调用 Listener1,因为他监听 GameEventChannel.Two 哪个事件想要调用。

所有代码

  public enum GameEventChannel {
        One = 1,
        Two = 2,
        Three = 4,
        Four = 8,
        Five = 16,
        Six = 32,
        Seven = 64,
        Eight = 128,
        Nine = 256,
        Ten = 512
    }    

    public void Invoke(GameEventChannel channels)
    {

        for (var i = 0; i < _Listeners.Count; i++)
        {
            var listener = _Listeners[i];
            if (listener != null && IsListeningToChannel())
            {
                _Listeners[i]?.OnEventInvoked();
            }
        }
    }

     public bool IsListeningToChannel(GameEventChannel listenerChannel, GameEventChannel eventChannels)
    {
        return AnyOfListenerChanelFlagInsideEventChannelFlags;
    }

编辑 1: 将枚举的每次出现更改为正确的名称 编辑 2: 为枚举添加了完整代码(现在包括属性)

虽然史蒂夫的回答——现在被神秘地删除了——是正确的,但它可以改进。

首先,正确构建枚举。 Flag 枚举应该这样标记,并且应该有一个 None 值。您也可以考虑使用二进制文字来使其更清晰。

[Flags] public enum Channel 
{
  None = 0b0000_0000_0000,
  One  = 0b0000_0000_0001,
  Two  = 0b0000_0000_0010,
  ...

我的建议是您实现一个扩展方法来计算您想要的内容,并适当命名。例如,如果您想要的是 "has any of the given channels":

static class Extensions 
{
  public static bool HasAnyChannel(
      this Channel x,
      Channel y) =>
    x & y != Channel.None;
}

现在您可以使用表达式

listenerChannels.HasAnyChannel(eventChannels)

易于阅读和理解。