c# - 如何在 .NET Standard 中为通用枚举类型设置枚举标志?

标签 c# .net reflection enums .net-standard

我想使用 .NET Standard 实现以下方法:

public static void SetFlag<TEnum>(ref TEnum value, TEnum flag)
    where TEnum : Enum

我花了几个小时试图实现这一目标:

  • 通过反射获取|运算符对于原始类型来说似乎是不可能的,因为enum是。
  • 使用 dynamic 需要引用一个额外的包 (Microsoft.CSharp.RuntimeBinder),但我希望我的库保持纯 .NET符合标准。

我最近的想法是手动比较 TEnum{byte 的每个有效枚举类型,sbyte, short, ushort, int, uint, long >,ulong。但这感觉真的很奇怪和肮脏:

try
{
    var v = (byte)(object)value | (byte)(object)flag;
    value = (TEnum)(object)v;
    return;
}
catch (InvalidCastException) { }

try
{
    var v = (int)(object)value | (int)(object)flag;
    value = (TEnum)(object)v;
    return;
}
catch (InvalidCastException) { }

// ...

throw new NotSupportException($"Unknown enum type {typeof(TEnum)}");

那么这真的是 .NET(标准)在这里提供的唯一选项还是我缺少的?期待您的指点!

编辑: 不是 this question 的副本;我正在使用 C# 7.3 和通用 Enum 约束。

最佳答案

它不是最便宜的(所有东西都被装箱,有一些反射等等),但你总是可以这样做:

private static void SetFlag<T>(ref T value, T flag) where T : Enum
{
    // 'long' can hold all possible values, except those which 'ulong' can hold.
    if (Enum.GetUnderlyingType(typeof(T)) == typeof(ulong))
    {
        ulong numericValue = Convert.ToUInt64(value);
        numericValue |= Convert.ToUInt64(flag);
        value = (T)Enum.ToObject(typeof(T), numericValue);
    }
    else
    {
        long numericValue = Convert.ToInt64(value);
        numericValue |= Convert.ToInt64(flag);
        value = (T)Enum.ToObject(typeof(T), numericValue);
    }
}

你仍然有一些重复,但至少它被限制在long/ulong。如果你可以假设你的标志枚举成员不会有负值,你可以使用:

private static void SetFlag<T>(ref T value, T flag) where T : Enum
{
    ulong numericValue = Convert.ToUInt64(value);
    numericValue |= Convert.ToUInt64(flag);
    value = (T)Enum.ToObject(typeof(T), numericValue);
}

关于c# - 如何在 .NET Standard 中为通用枚举类型设置枚举标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55516825/

相关文章:

c# - 在 Windows 窗体应用程序中 Hook 消息循环?

c# - DataGrid 选择整列

c# - 将 javascript 日期时间转换为 C#/VB.NET 日期时间

c# - BinaryFormatter 对象图升级

c# - 在运行时解析成员名称

c# - 组合框的默认文本

.net - ASP.net UpdatePanel 控件中可能存在错误?

c# - WPF locbaml-ed 应用程序和运行时语言切换?

java - 如何知道java中包的类?

typescript - 获取类的属性