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没有这个问题?
ImmutableListImmutableList<T>.Empty是一个单例的空链表节点。当用集合初始化器[]创建空的ImmutableList时,底层会直接返回这个单例实例,加上ImmutableList的相等比较是基于内容(空实例本身就是同一个对象),所以所有比较结果都是True。
内容的提问来源于stack exchange,提问作者Matthew Layton
相关产品推荐
相关产品推荐

