繁体   English   中英

检查标志是否包含其他标志的任何值

[英]Check if flag contains any value of other flag

我想比较两个标志,看看它们是否有任何共同价值。
我希望有一个扩展方法来“加速”编码(我将经常在各种枚举类型上使用它)。 我怎么能够?
这段代码告诉我:

运算符 '&' 不能应用于枚举类型和枚举类型的操作数

public enum Tag
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 4,
    Value4 = 8,
    Value5 = 16
}

public static class FlagExt
{
    public static bool HasAny(this Enum me, Enum other)
    {
        return (me & other) != 0;
    }
}

public class Program
{
    public static void Main()
    {
        Tag flag1 = Tag.Value1 | Tag.Value2 | Tag.Value3;
        Tag flag2 = Tag.Value2 | Tag.Value3 | Tag.Value4;
        
        Console.WriteLine(flag1.HasAny(flag2)); // it should returns true. flag1.HasFlag(flag2) returns false.
    }
}

我也试过这个:

    return (((int)me) & ((int)other)) != 0;

但它引发了错误:

无法将类型“System.Enum”转换为“int”

根据这个答案( How to convert from System.Enum to base integer?

您需要使用异常处理程序包装此代码,或者以其他方式确保两个枚举都包含 integer。

public static class FlagExt
{
    public static bool HasAny(this Enum me, Enum other)
    {
        return (Convert.ToInt32(me) & Convert.ToInt32(other)) != 0;
    }
}

如果你想要一个非常通用的枚举HasAny扩展,你可以执行以下操作。 我已经测试过这适用于枚举可以是的所有不同的底层类型。 此外,如果您正在检查标志,您可能应该使用[Flags]属性装饰您的枚举,因此这将检查被检查的枚举是否具有该属性。

public static class FlagExtensions
{
    public static bool HasAny(this Enum enumLeft, Enum enumRight)
    {
        if (enumLeft.GetType() != enumRight.GetType())
            throw new ArgumentException("enum types should be the same");
        
        if (!enumLeft.GetType().IsDefined(typeof(FlagsAttribute), inherit: false))
            throw new ArgumentException("enum type should have the flags attribute");
        
        dynamic enumLeftValue = Convert.ChangeType(enumLeft, enumLeft.GetTypeCode());
        dynamic enumRightValue = Convert.ChangeType(enumRight, enumRight.GetTypeCode());
        return (enumLeftValue & enumRightValue) != 0;
    }
}

我也试过这个:

 return (((int)me) & ((int)other));= 0;

但它引发了错误:

 Cannot convert type 'System.Enum' to 'int'

枚举始终实现 IConvertible 并且 IConvertible 具有“ToInt32”。 所以你可以这样写:

public static class FlagExt
{
    public static bool HasAny<TEnum>(this TEnum me, TEnum other) 
            where TEnum : Enum, IConvertible
    {
        return (me.ToInt32(null) & other.ToInt32(null)) != 0;
    }
}

    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM