IReadOnlyList<T>

IReadOnlyList<T> 是 .NET 中的一个重要接口,代表一个只读的元素集合。下面是关于它的详细解释:

基本定义

1 public interface IReadOnlyList<out T> : IReadOnlyCollection<T>, IEnumerable<T>
2 {
3     T this[int index] { get; }
4 }

核心特性

1. 只读访问

  • 只能读取元素,不能修改

  • 没有 Add()Remove()Clear() 等方法

  • 索引器只有 getter(this[int index]

2. 索引支持

  • 可以通过从0开始的整数索引直接访问元素

  • 支持随机访问,时间复杂度通常为 O(1)

3. 继承关系

1 IEnumerable<T>
2 3 IReadOnlyCollection<T> // 添加了 Count 属性 4 5 IReadOnlyList<T> // 添加了索引器

常见实现

内置类型

 1 // 数组
 2 int[] array = new int[] { 1, 2, 3 };
 3 IReadOnlyList<int> readOnlyArray = array;
 4 
 5 // List<T>(实现了 IReadOnlyList<T>)
 6 List<string> list = new List<string> { "A", "B", "C" };
 7 IReadOnlyList<string> readOnlyList = list;
 8 
 9 // ArraySegment<T>
10 ArraySegment<int> segment = new ArraySegment<int>(array, 1, 2);
11 IReadOnlyList<int> readOnlySegment = segment;

专用只读集合

1 // ReadOnlyCollection<T>(包装器)
2 List<int> originalList = new List<int> { 1, 2, 3 };
3 ReadOnlyCollection<int> readOnly = new ReadOnlyCollection<int>(originalList);
4 IReadOnlyList<int> readOnlyList = readOnly;

使用场景

1. API 设计

 1 // 作为返回值 - 明确表示数据是只读的
 2 public IReadOnlyList<string> GetLogEntries()
 3 {
 4     return _logEntries.AsReadOnly();
 5 }
 6 
 7 // 作为参数 - 明确表示方法不会修改传入的集合
 8 public void ProcessItems(IReadOnlyList<Item> items)
 9 {
10     foreach (var item in items)
11     {
12         // 只能读取,不能修改
13     }
14 }

2. 性能优化

1 // 避免不必要的复制
2 public IReadOnlyList<T> GetSlice(int start, int count)
3 {
4     // 返回原始数据的只读视图,不复制数据
5     return new ArraySegment<T>(_data, start, count);
6 }

3. 线程安全考虑

 1 // 在需要共享数据的多线程场景中
 2 public class DataProcessor
 3 {
 4     private readonly IReadOnlyList<Data> _sharedData;
 5     
 6     public DataProcessor(IReadOnlyList<Data> data)
 7     {
 8         _sharedData = data;  // 多个处理器可以安全地共享只读数据
 9     }
10 }

与相关接口的比较

接口索引访问修改操作计数主要用途
IEnumerable<T> 最基本枚举
ICollection<T> 可修改集合
IList<T> 可修改索引集合
IReadOnlyCollection<T> 只读集合
IReadOnlyList<T> 只读索引集合

 

 

最佳实践

  1. 优先使用 IReadOnlyList<T> 作为参数

1 // 好 - 明确表示不会修改
2 public void PrintNames(IReadOnlyList<string> names)
3 
4 // 不好 - 可能被误认为会修改
5 public void PrintNames(List<string> names)

在不需要修改时返回 IReadOnlyList<T>

1 public IReadOnlyList<Customer> GetActiveCustomers()
2 {
3     return _customers.Where(c => c.IsActive).ToList();
4 }

注意性能

1 // 如果需要频繁的随机访问,使用 IReadOnlyList<T>
2 // 如果只需要遍历,使用 IEnumerable<T> 可能更合适

与 LINQ 配合

1 IReadOnlyList<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
2 
3 // LINQ 方法返回 IEnumerable<T>,如果需要 IReadOnlyList<T>:
4 IReadOnlyList<int> evenNumbers = numbers.Where(n => n % 2 == 0).ToList();

 

// 在需要共享数据的多线程场景中public class DataProcessor{    private readonly IReadOnlyList<Data> _sharedData;        public DataProcessor(IReadOnlyList<Data> data)    {        _sharedData = data;  // 多个处理器可以安全地共享只读数据    }}
posted @ 2025-12-12 13:55  家煜宝宝  阅读(52)  评论(0)    收藏  举报