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

如何在C#中构建仅按引用相等性比较元素的泛型集合?

按引用相等性比较的泛型集合实现方案

要实现你需要的——仅通过对象引用而非值来判断相等性的集合,.NET框架已经提供了开箱即用的解决方案,不用手动实现复杂的相等逻辑。

核心工具:ReferenceEqualityComparer

.NET Core 2.1+ 和 .NET 5+ 中内置了ReferenceEqualityComparer类,它实现了IEqualityComparer<T>接口:

  • Equals方法直接调用Object.ReferenceEquals,严格按引用判断对象是否相同
  • GetHashCode返回基于对象引用的哈希值,而非值的哈希值,确保引用不同的对象即使值相同也能被正确区分

字符串场景示例

结合HashSet<T>使用这个比较器,就能实现你的需求:引用相同的字符串仅存一份,值相同但引用不同的可以共存。

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

class Program
{
    static void Main()
    {
        string s1 = "String1";
        string s2 = "String1";
        string suffix = "A";
        string s3 = "String" + suffix;
        string s4 = "String" + suffix;

        // 创建使用引用相等比较器的HashSet
        var referenceSet = new HashSet<string>(ReferenceEqualityComparer.Instance);
        
        referenceSet.Add(s1);
        referenceSet.Add(s2); // 与s1引用相同,添加失败,集合仅保留一份
        referenceSet.Add(s3);
        referenceSet.Add(s4); // 与s3引用不同,添加成功,集合同时包含s3和s4

        Console.WriteLine($"集合元素数量:{referenceSet.Count}"); // 输出:3
        foreach (var str in referenceSet)
        {
            Console.WriteLine($"元素:{str},引用哈希:{RuntimeHelpers.GetHashCode(str)}");
        }
    }
}

扩展到任意泛型引用类型

该方案适用于所有引用类型,比如自定义类的场景:

// 自定义测试类
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        var p1 = new Person { Name = "Alice", Age = 30 };
        var p2 = p1; // 与p1引用相同
        var p3 = new Person { Name = "Alice", Age = 30 }; // 值相同但引用不同

        var personSet = new HashSet<Person>(ReferenceEqualityComparer.Instance);
        personSet.Add(p1);
        personSet.Add(p2); // 添加失败
        personSet.Add(p3); // 添加成功

        Console.WriteLine($"Person集合元素数量:{personSet.Count}"); // 输出:2
    }
}

封装自定义集合(可选)

如果需要频繁使用这类集合,可以封装一个简化版的自定义集合:

public class ReferenceHashSet<T> : HashSet<T> where T : class
{
    public ReferenceHashSet() : base(ReferenceEqualityComparer.Instance) { }
    public ReferenceHashSet(IEnumerable<T> collection) : base(collection, ReferenceEqualityComparer.Instance) { }
}

// 使用时直接实例化
var set = new ReferenceHashSet<string>();

兼容.NET Framework的替代实现

如果需要兼容.NET Framework(该环境无内置ReferenceEqualityComparer),可以手动实现一个简单的引用比较器:

public class ReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class
{
    public static readonly ReferenceEqualityComparer<T> Instance = new();

    public bool Equals(T x, T y) => ReferenceEquals(x, y);
    public int GetHashCode(T obj) => RuntimeHelpers.GetHashCode(obj);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:28:23