You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#泛型Enum参数中实现高效类型安全的比较操作?

泛型Enum参数无装箱高性能比较方案(.NET 9/C# 13)

针对泛型枚举比较引发的编译错误、子类兼容性及数值类型兼容问题,结合.NET 9的新特性,提供以下几种无装箱、类型安全且高性能的解决方案:

方案1:利用.NET 9新增数值接口约束(推荐)

.NET 9为所有枚举的底层数值类型(含UInt64)实现了INumberBase<T>和IEqualityOperators<T,T,bool>接口,且C# 13允许对枚举类型应用这些接口约束。添加约束后可直接使用==运算符比较,完全无装箱且编译期类型安全。

代码示例

public class FiniteStateMachine<TState, TCommand>
    where TState : Enum, INumberBase<TState>, IEqualityOperators<TState, TState, bool>
    where TCommand : Enum, INumberBase<TCommand>, IEqualityOperators<TCommand, TCommand, bool>
{
    public FiniteStateMachine(TState initialState)
    {
        // 直接使用==比较,无编译错误且无装箱
        if (initialState == default(TState))
        {
            // 自定义处理逻辑
        }
    }
}

// 子类需继承父类的泛型约束以保证编译通过
public class RouterFiniteStateMachine<TState, TCommand> : FiniteStateMachine<TState, TCommand>
    where TState : Enum, INumberBase<TState>, IEqualityOperators<TState, TState, bool>
    where TCommand : Enum, INumberBase<TCommand>, IEqualityOperators<TCommand, TCommand, bool>
{
    public RouterFiniteStateMachine(TState initialState) : base(initialState)
    {
    }
}

优点

  • 代码简洁直观,直接使用原生==运算符
  • 编译期类型校验,避免运行时错误
  • 静态绑定运算符调用,性能最优(无装箱、无反射)

方案2:使用EqualityComparer<T>.Default(无需修改泛型约束)

若不想添加额外泛型约束,或子类继承约束存在阻碍,可使用EqualityComparer<T>.Default.Equals方法。.NET中所有枚举会隐式实现IEquatable<TEnum>,该方法会自动调用无装箱的Equals实现,性能接近直接运算符调用。

代码示例

public class FiniteStateMachine<TState, TCommand>
    where TState : Enum
    where TCommand : Enum
{
    public FiniteStateMachine(TState initialState)
    {
        if (EqualityComparer<TState>.Default.Equals(initialState, default(TState)))
        {
            // 自定义处理逻辑
        }
    }
}

// 子类无需额外约束,直接继承即可编译
public class RouterFiniteStateMachine<TState, TCommand> : FiniteStateMachine<TState, TCommand>
    where TState : Enum
    where TCommand : Enum
{
    public RouterFiniteStateMachine(TState initialState) : base(initialState)
    {
    }
}

优点

  • 无需修改泛型约束,子类编译无阻碍
  • 无装箱操作,性能优异
  • 类型安全,编译期检查参数类型

方案3:通过Unsafe类直接转换底层数值(极致性能)

若追求极致性能,可使用System.Runtime.CompilerServices.Unsafe类将枚举直接转换为底层数值类型比较,完全绕开枚举类型包装,无任何额外开销。

代码示例

先创建静态工具类封装枚举比较逻辑:

public static class EnumComparer<TEnum> where TEnum : Enum
{
    private static readonly Func<TEnum, TEnum, bool> _equalsFunc;

    static EnumComparer()
    {
        var underlyingType = Enum.GetUnderlyingType(typeof(TEnum));
        // 根据底层类型创建对应比较委托
        _equalsFunc = underlyingType switch
        {
            Type t when t == typeof(byte) => (a, b) => Unsafe.As<TEnum, byte>(ref a) == Unsafe.As<TEnum, byte>(ref b),
            Type t when t == typeof(sbyte) => (a, b) => Unsafe.As<TEnum, sbyte>(ref a) == Unsafe.As<TEnum, sbyte>(ref b),
            Type t when t == typeof(short) => (a, b) => Unsafe.As<TEnum, short>(ref a) == Unsafe.As<TEnum, short>(ref b),
            Type t when t == typeof(ushort) => (a, b) => Unsafe.As<TEnum, ushort>(ref a) == Unsafe.As<TEnum, ushort>(ref b),
            Type t when t == typeof(int) => (a, b) => Unsafe.As<TEnum, int>(ref a) == Unsafe.As<TEnum, int>(ref b),
            Type t when t == typeof(uint) => (a, b) => Unsafe.As<TEnum, uint>(ref a) == Unsafe.As<TEnum, uint>(ref b),
            Type t when t == typeof(long) => (a, b) => Unsafe.As<TEnum, long>(ref a) == Unsafe.As<TEnum, long>(ref b),
            Type t when t == typeof(ulong) => (a, b) => Unsafe.As<TEnum, ulong>(ref a) == Unsafe.As<TEnum, ulong>(ref b),
            _ => throw new NotSupportedException($"不支持枚举{typeof(TEnum)}的底层类型{underlyingType}")
        };
    }

    public static bool Equals(TEnum a, TEnum b) => _equalsFunc(a, b);
}

在状态机中使用工具类:

public class FiniteStateMachine<TState, TCommand>
    where TState : Enum
    where TCommand : Enum
{
    public FiniteStateMachine(TState initialState)
    {
        if (EnumComparer<TState>.Equals(initialState, default(TState)))
        {
            // 自定义处理逻辑
        }
    }
}

优点

  • 极致性能,无装箱、无接口调用开销
  • 兼容所有底层数值类型(包括UInt64)

缺点

  • 代码相对复杂,需提前初始化比较委托
  • 依赖Unsafe类,需启用unsafe代码或引用System.Runtime.CompilerServices.Unsafe NuGet包

内容的提问来源于stack exchange,提问作者Raheel Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:03:14