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

C# 12中ImmutableArray空集合初始化器与Empty属性为何不等?

为什么C# 12中ImmutableArray<T>.Empty和集合初始化器[]创建的空实例不相等?

示例代码:

using System;
using System.Collections.Immutable;

public class Program
{
    public static void Main()
    {
        ImmutableArray<object> a = ImmutableArray<object>.Empty;
        ImmutableArray<object> b = ImmutableArray<object>.Empty;
        ImmutableArray<object> c = [];
        ImmutableArray<object> d = [];
        
        Console.WriteLine($"a == b: {a == b}");
        Console.WriteLine($"a == c: {a == c}");
        Console.WriteLine($"c == d: {c == d}");
    }
}

运行结果:

a == b: True
a == c: False
c == d: True


这个差异的核心在于ImmutableArray的本质和两种创建方式的底层实现不同:

  • ImmutableArray<T>.Empty是一个预定义的共享静态实例,所有通过Empty获取的空ImmutableArray,内部指向的都是同一个空数组引用。因为ImmutableArray的==运算符重载是直接比较内部数组的引用是否相同,所以a == b返回True。
  • C# 12的集合初始化器[]创建空ImmutableArray时,编译器会生成调用ImmutableArray<T>.Builder的逻辑:先创建一个builder,因为没有添加任何元素,最终调用Builder.ToImmutable()生成实例。而这个方法在处理空builder时,会新建一个空数组实例,并不会复用ImmutableArray<T>.Empty的共享数组。因此a(来自Empty)和c(来自集合初始化器)的内部数组引用不同,==比较返回False。
  • 至于c == d返回True,是因为编译器在同一编译单元内对相同的空集合初始化器做了优化,复用了同一个实例,所以它们的内部数组引用一致。

补充:为什么ImmutableList没有这个问题?

ImmutableList的设计逻辑不同:ImmutableList<T>.Empty是一个单例的空链表节点。当用集合初始化器[]创建空的ImmutableList时,底层会直接返回这个单例实例,加上ImmutableList的相等比较是基于内容(空实例本身就是同一个对象),所以所有比较结果都是True。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:00:15