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

如何调整泛型约束匹配HashSet的EqualityComparer<T>.Default要求?

问题原因

你遇到的ImmutableArray<T>测试失败问题,本质是ImmutableArray<T>的默认相等比较逻辑不符合你的预期:EqualityComparer<ImmutableArray<T>>.Default使用的比较逻辑是基于底层数组的引用相等,而非内容的结构相等。你两次调用ImmutableArray.Create生成的是底层数组不同的两个实例,默认比较会判定为不相等,所以HashSet的计数会变成2,和你的测试断言冲突。

方案1:调整泛型约束仅适配默认比较器逻辑

如果你就是要验证EqualityComparer<T>.Default的原生行为,只需要把原来的泛型约束里的struct限制去掉,就可以同时支持值类型和string这类符合默认比较预期的引用类型:

// 仅使用默认比较器的版本
bool IsDefaultHashEqual<T>(Func<T> f) where T : IEquatable<T>
{
    var set = new HashSet<T>();
    set.Add(f());
    set.Add(f());
    return set.Count == 1;
}

这个版本下ImmutableArray<T>的测试返回false是符合预期的,因为默认比较器确实不会做结构相等判断。

方案2:自动识别需要结构相等的类型

如果你希望方法自动对支持结构相等的类型使用StructuralComparisons.StructuralEqualityComparer,可以在运行时判断类型是否实现了IStructuralEquatable接口,动态选择比较器,不需要额外的泛型约束:

bool IsHashEqual<T>(Func<T> f)
{
    IEqualityComparer<T> comparer = typeof(IStructuralEquatable).IsAssignableFrom(typeof(T))
        ? (IEqualityComparer<T>)StructuralComparisons.StructuralEqualityComparer
        : EqualityComparer<T>.Default;
    
    var set = new HashSet<T>(comparer);
    set.Add(f());
    set.Add(f());
    return set.Count == 1;
}

这个版本会自动对数组、ImmutableArray<T>等实现了IStructuralEquatable的类型使用结构比较,其他类型沿用默认比较逻辑,你原来的基础类型、字符串测试都可以正常通过,ImmutableArray<T>的测试也会按内容相等返回true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:18:03