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

.NET是否有支持自定义元素比较的集合逐元素Compare方法?

解决方案

针对你需要的跨.NET版本(4.8/4.8.1、6.0、8.0)的集合逐元素比较需求,以下是符合要求的内置方法/实现方式:

.NET 6.0+(含.NET 8.0)

直接使用Span<T>.CompareTo(Span<T>, IComparer<T>)方法,配合CollectionsMarshal.AsSpan将IReadOnlyCollection<string>转换为Span<string>,完美支持自定义元素比较器,返回-1/0/1的标准比较结果:

using System.Collections.Generic;
using System.Runtime.InteropServices;

// 调用示例
IReadOnlyCollection<string> coll1 = new[] { "apple", "banana" };
IReadOnlyCollection<string> coll2 = new[] { "Apple", "Banana" };
int comparisonResult = CollectionsMarshal.AsSpan(coll1)
    .CompareTo(CollectionsMarshal.AsSpan(coll2), StringComparer.OrdinalIgnoreCase);

该方法会按顺序逐元素比较,首个不同元素的比较结果即为整体结果;若一个集合是另一个的前缀,较短的集合视为更小。

.NET Framework 4.8/4.8.1

.NET Framework中没有直接提供带自定义元素比较器的集合逐元素比较内置方法,但可以通过Comparer<IEnumerable<string>>.Create创建可复用的比较器,内部逻辑依赖内置的元素比较器,无需自行编写通用遍历逻辑:

using System.Collections.Generic;

// 预定义可复用的集合比较器
private static readonly Comparer<IEnumerable<string>> _ordinalStringCollectionComparer =
    Comparer<IEnumerable<string>>.Create((a, b) =>
    {
        using var enumA = a.GetEnumerator();
        using var enumB = b.GetEnumerator();
        
        while (true)
        {
            bool hasNextA = enumA.MoveNext();
            bool hasNextB = enumB.MoveNext();
            
            if (!hasNextA && !hasNextB) return 0;
            if (!hasNextA) return -1;
            if (!hasNextB) return 1;
            
            int elemCompare = StringComparer.Ordinal.Compare(enumA.Current, enumB.Current);
            if (elemCompare != 0) return elemCompare;
        }
    });

// 调用示例
int comparisonResult = _ordinalStringCollectionComparer.Compare(coll1, coll2);

自定义类的IComparable实现

结合上述方案,自定义类的CompareTo方法可以这样写,实现跨版本兼容:

using System;
using System.Collections.Generic;
#if NET6_0_OR_GREATER
using System.Runtime.InteropServices;
#endif

public class MyCustomClass : IComparable<MyCustomClass>
{
    public IReadOnlyCollection<string> MyCollection { get; }

    public MyCustomClass(IReadOnlyCollection<string> collection)
    {
        MyCollection = collection;
    }

    public int CompareTo(MyCustomClass other)
    {
        if (other == null) return 1;
        
#if NET6_0_OR_GREATER
        return CollectionsMarshal.AsSpan(MyCollection)
            .CompareTo(CollectionsMarshal.AsSpan(other.MyCollection), StringComparer.Ordinal);
#else
        return _ordinalStringCollectionComparer.Compare(MyCollection, other.MyCollection);
#endif
    }

#if !NET6_0_OR_GREATER
    private static readonly Comparer<IEnumerable<string>> _ordinalStringCollectionComparer =
        Comparer<IEnumerable<string>>.Create((a, b) =>
        {
            using var enumA = a.GetEnumerator();
            using var enumB = b.GetEnumerator();
            
            while (true)
            {
                bool hasNextA = enumA.MoveNext();
                bool hasNextB = enumB.MoveNext();
                
                if (!hasNextA && !hasNextB) return 0;
                if (!hasNextA) return -1;
                if (!hasNextB) return 1;
                
                int elemCompare = StringComparer.Ordinal.Compare(enumA.Current, enumB.Current);
                if (elemCompare != 0) return elemCompare;
            }
        });
#endif
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:28:14