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

C#编译器是否会优化表达式体成员重复求值?如何复用集合实例?

问题解答

编译器会优化为单实例吗?

不会。你的理解完全正确——表达式体属性(=>)每次被访问时,都会执行右侧的表达式。不管是用new() { ... }初始化列表,还是用集合表达式[...],每次访问Names都会创建一个全新的List<string>实例。C#编译器不会做“复用实例”的优化,因为这会改变代码语义(比如外部修改返回列表时,不同访问拿到的实例状态会不一致,编译器不会擅自假设你不需要这种行为)。

集合表达式和new()初始化有区别吗?

没有本质区别。集合表达式是C# 10+引入的语法糖,针对List<string>场景,编译器会把[...]编译成和new List<string> { ... }几乎一致的代码——同样是每次执行时创建新列表实例、填充元素后返回。两种写法在实例创建的行为上完全相同。

如何实现只返回一个实例?

要避免每次访问都创建新实例,需要把列表实例提前初始化并存储,让属性直接返回这个预创建的实例。常见方案有以下几种:

1. 用只读字段存储实例,属性返回该字段

这是最简单的方案,适用于允许外部修改集合内容的场景:

private readonly List<string> _names = new() { "Foo", "Bar", "Baz" };
public List<string> Names => _names;

注意:如果外部代码调用Names.Add("Qux"),会直接修改内部的_names集合,因为返回的是同一个实例的引用。

2. 返回不可变集合(推荐)

如果不想让外部修改集合内容,可以使用.NET的不可变集合类型(比如ImmutableList<T>):

using System.Collections.Immutable;

private readonly ImmutableList<string> _names = ImmutableList.Create("Foo", "Bar", "Baz");
public ImmutableList<string> Names => _names;

也可以用集合表达式简化初始化:

using System.Collections.Immutable;

private readonly ImmutableList<string> _names = ["Foo", "Bar", "Baz"].ToImmutableList();
public ImmutableList<string> Names => _names;

不可变集合的所有修改操作都会返回新实例,不会影响原集合,安全性更高。

3. 返回只读包装器

如果必须返回List<string>或IReadOnlyList<T>,同时防止外部修改集合,可以用AsReadOnly()方法返回只读包装:

private readonly List<string> _names = new() { "Foo", "Bar", "Baz" };
public IReadOnlyList<string> Names => _names.AsReadOnly();

这样外部只能读取集合元素,无法执行添加、删除等修改操作(调用修改方法会抛出NotSupportedException)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:25:59