允许按位运算的通用约束?

2024-04-24

我有一个enum :

  public enum Flags {
        COMMAND_MSG = 1,
        COMMAND_FILE = 2,
        COMMAND_ACTION = 4,
      }

现在,假设我设置了多个值,例如:

Flags g = Flags.COMMAND_ACTION |Flags.COMMAND_MSG; 

所以我有一个有价值的 int5.

现在,从那5我想看到它是以下内容的组合:Flags.COMMAND_ACTION |Flags.COMMAND_MSG;

(Notice,我没有[Flags]属性,因为我使用的是 protobuff 库,并且枚举是 auto生成的。

我尝试过什么:

public string Show (Flags item)
{
  var s="";
  string.Join(",", Enum.GetValues(typeof(Flags))
        .Cast<Flags>() 
        .Select(f=>(f & item) >0 ?f.ToString() :"") //check if bit is set
        .Where(f=>!string.IsNullOrWhiteSpace(f))); //remove empty
  return s;
}

So Show(5);确实显示:COMMAND_MSG,COMMAND_ACTION

那么问题出在哪里呢?

我想将其转换为通用扩展方法:

 public static string ToFlags<T>(this int val, T FlagType) where T : ??

    {
        return string.Join(",", Enum.GetValues(typeof(T))
                     .Cast<T>()
                     .Select(enumEntry => (enumEntry & val) > 0 ? enumEntry.ToString() : "")
                     .Where(f => !string.IsNullOrWhiteSpace(f)));
    }

但有一个错误,因为:

问题 :

我应该应用哪种通用约束才能使其发挥作用?


对于这种情况,没有适当的泛型类型约束。您可以应用按位运算ints,因此将 enum 值转换为 int。T不能投射到int直接地;不过,你可以绕道而行object.

public static string ToFlags<T>(this T val)
    where T : struct
{
    return string.Join(",", Enum.GetValues(typeof(T))
        .Cast<T>()
        .Select(enumEntry => ((int)(object)enumEntry & (int)(object)val) > 0
            ? enumEntry.ToString() : "")
        .Where(f => !string.IsNullOrWhiteSpace(f)));
}

注意:数字也有类似的情况。你不能说where T : number并对 T 类型的值应用数字运算符。(请参阅下面我的更新)

你也可以做val a T并且您不必传递类型T作为方法参数。您已经将其作为泛型类型参数传递。这就足够了。编译器也足够聪明来推断T,因此在调用该方法时不必指定它。

// Test
Flags item = Flags.COMMAND_ACTION | Flags.COMMAND_MSG;
Console.WriteLine(item.ToFlags());

您可以指定struct作为泛型类型约束,作为struct代表值类型。它并不完美,但比完全没有约束要好。


Update

距离提出这个问题已经过去很长时间了。 C#11 介绍接口中的静态虚拟成员 https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members和 .NET 7 BCL 接口IBitwiseOperators https://learn.microsoft.com/en-us/dotnet/api/system.numerics.ibitwiseoperators-3 and IEqualityOperators https://learn.microsoft.com/en-us/dotnet/api/system.numerics.iequalityoperators-3。这些接口(和许多其他人 https://learn.microsoft.com/en-us/dotnet/api/system.numerics) 是针对数字类型实现的,但遗憾的是不适用于枚举。

See: [API 提案]:Enum 应实现 IBitwiseOperators、IEqualityOperators #81664 https://github.com/dotnet/runtime/issues/81664.

从 C# 7.3 开始,有一个枚举通用约束 https://devblogs.microsoft.com/premier-developer/dissecting-new-generics-constraints-in-c-7-3/#the-enum-constraint除了可以指定struct.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

允许按位运算的通用约束? 的相关文章

随机推荐

  • Excel IF函数大于x但小于y

    我正在尝试安排一列 以便基本上可以对结果进行 评分 我正在寻找一个公式 该公式将 如果大于 100000 但小于 110000 10 如果大于 90000 但小于 99999 9等等 有人可以帮忙吗 我们可以将 LOOKUP 与范围一起使用
  • XPage:处理浏览器后退按钮

    我为 Notes 表单创建了一个 XPage 我添加了一个编辑按钮 用于执行一些逻辑 然后将文档模式切换为 编辑 以及一个保存并关闭按钮 用于保存文档并重定向到 Notes 视图的 XPage 这工作正常 但是当返回视图后按下浏览器后退按钮
  • Hudson 和 maven-release-plugin

    我正在使用 Hudsonmaven 发布 插件 http maven apache org plugins maven release plugin 如您所知 maven release plugin 构建项目分两步 release pre
  • 使用 matplotlib 绘制亚像素精度散点图?

    注 我在写这个问题时找到了解决方案 我的回答如下 有没有一种简单的方法可以使用 matplotlib 获得圆的亚像素抗锯齿放置 我能够创建以下 gif 但圆圈的运动以整数像素为单位这一事实确实困扰着我 我当然可以渲染一个大图像 plt sa
  • 当 Button.CommandProperty 为 null 时如何禁用按钮

    简短说明 Button CommandProperty 绑定到 ViewModel 的 SomeObject SomeCommand 属性 当 SomeObject 的 SomeCommand 属性设置为 null 或整个 SomeObje
  • 如何从 url 中提取 &client= ? [复制]

    这个问题在这里已经有答案了 如果我的网址是http link ads blogspot com url http could be any url com name 123456789101112 using 纯JavaScript我该如何
  • PhotoChooserTask 后未触发 ApplicationBar 图标按钮单击事件

    我无法在某些条件下触发 ApplicationBarIconButton 的单击事件 我尝试简化重现它所需的步骤 1 创建一个新的Windows Phone应用程序 2 添加新页面 Page1 xaml 3 在 MainPage xaml
  • 如何获取 TeamCity Build 触发器过滤器来构建功能分支而不是默认分支

    我创建了一个 Team City 构建来构建功能分支 默认分支 refs heads development 分支规范 refs heads feature 我有一个 vcs 触发器 因此它会为每次 git 推送而构建 但我不希望它在有人推
  • 如何使用 JavaScript 检查按钮是否被点击

    有没有一种简单的方法可以沿着这些思路做一些事情 JavaScript if document getElementById button clicked true alert button was clicked HTML
  • 将glm四元数转换为旋转矩阵并与opengl一起使用

    所以我将对象的方向存储在 glm fquat 中 我想用它来旋转我的模型 我怎么做 我试过这个 glPushMatrix glTranslatef position x position y position z glMultMatrixf
  • 编译器可以将函数范围的、非静态的 const 数组存储在常量数据中并避免每次调用初始化吗?

    读书中字符数组 字符串如何存储在二进制文件 C C 中 https stackoverflow com q 71932148 364696 我在思考原始字符串涉及的各种方式 Nancy 将在生成的二进制文件中完好无损地显示 那个帖子的案例是
  • 文件类型 .pl 关联并使用 cmd.exe 运行脚本

    我创建了一个新的文件类型 pl 资源管理器 gt 工具 gt 文件夹选项 gt 文件类型 现在我想创建一个新的操作 它将调用 cmd exe 并自动运行 PERL 脚本 我不知道在 用于执行操作的应用程序 下要写什么 我必须向 cmd ex
  • 在 R 中将 NA 设置为 0

    将一个数据帧与另一个数据帧合并后 偶尔会留下随机的 NA 我想将这些 NA 设置为 0 以便我可以用它们执行计算 我正在尝试这样做 bothbeams data within bothbeams data bothbeams data x
  • NSMutableArray 不添加对象[重复]

    这个问题在这里已经有答案了 我认为 我犯了一个非常基本的错误 但我正在使用NSMutableArray这不知何故并没有添加对象 我正在按其方式发送它 我有一个属性 并合成 property nonatomic strong NSMutabl
  • 如何惯用地复制切片?

    在 Go 中 复制切片是标准操作 如下所示 It will figure out the details to match slice sizes dst copy dst n src m 在 Rust 中 我找不到类似的替换方法 我想出的
  • 如何将 ActiveRecord 模型属性从 json 迁移到 jsonb?

    迁移应该是什么样子 我想利用 jsonb 数组查询技术 我会这样写迁移 def change reversible do dir dir up change column models attribute jsonb USING CAST
  • 持久订阅 ActiveMQ

    我正在尝试为我的消息设置持久订阅者 以便即使在服务器重新启动后它们也能保留在主题中 但在配置过程中我收到与 xml 相关的错误 这是我的配置 xml
  • sin 和 cos 很慢,有其他选择吗?

    我的游戏需要移动一定的角度 为此 我通过 sin 和 cos 获得角度向量 不幸的是 正弦和余弦是我的瓶颈 我确信我不需要这么精确 是否有替代 C sin cos 和查找表的方法 既相当精确 又非常快 我发现了这个 float Skelet
  • TypeScript getter setter 约定

    TypeScript 中类属性的约定 标准 是什么 在 Angular 2 演示 来自 Angular io 的英雄之旅 中 所有属性都设置为 public export class Hero id number name string 所
  • 允许按位运算的通用约束?

    我有一个enum public enum Flags COMMAND MSG 1 COMMAND FILE 2 COMMAND ACTION 4 现在 假设我设置了多个值 例如 Flags g Flags COMMAND ACTION Fl