C#中让字典、列表、数组作为只读的方法参考
一、字典
在 C# 中,可以通过使用 ReadOnlyDictionary<TKey, TValue>
类或者是通过调用普通字典的 .AsReadOnly()
方法来创建一个只读的字典。ReadOnlyDictionary
不允许修改字典,任何试图改变字典的操作都会抛出 NotSupportedException
。
以下是使用 ReadOnlyDictionary<TKey, TValue>
类来返回一个只读字典的例子:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;class Program
{static void Main(){// 创建一个可修改的字典Dictionary<int, string> modifiableDict = new Dictionary<int, string>();modifiableDict.Add(1, "One");modifiableDict.Add(2, "Two");modifiableDict.Add(3, "Three");// 创建一个只读字典ReadOnlyDictionary<int, string> readOnlyDict = new ReadOnlyDictionary<int, string>(modifiableDict);// 返回只读字典foreach (var kvp in readOnlyDict){Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");}// 任何试图修改 readOnlyDict 的操作都会抛出异常// readOnlyDict.Add(4, "Four"); // NotSupportedException}
}
如果你想要创建并返回一个只读的字典,但不想引入 ReadOnlyDictionary<TKey, TValue>
的依赖,你可以定义一个返回 IReadOnlyDictionary<TKey, TValue>
的方法,例如:
public IReadOnlyDictionary<TKey, TValue> GetReadOnlyDictionary<TKey, TValue>(IDictionary<TKey, TValue> dictionary)
{return new ReadOnlyDictionary<TKey, TValue>(dictionary);
}
这样做的好处是你的方法签名不会显示具体的 ReadOnlyDictionary
类型,增强了代码的抽象化,只需知道返回的是一个不可变的字典接口。当然,实际返回的依然是 ReadOnlyDictionary
实例。调用者仅能通过 IReadOnlyDictionary
接口暴露的成员来使用这个字典,而不是 ReadOnlyDictionary
类的成员。
二、列表
在 C# 中,要返回一个只读的列表,可以使用 ReadOnlyCollection<T>
类,或者使用 LINQ 扩展方法 ToList().AsReadOnly()
来将一个 List<T>
转换为 IReadOnlyList<T>
。这样的列表对外部是不可变的,即不允许增加、删除或修改元素。
下面是如何使用 ReadOnlyCollection<T>
来创建只读列表的例子:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;public class Program
{public static void Main(){// 创建一个可变的列表List<int> modifiableList = new List<int> { 1, 2, 3 };// 创建一个只读的列表ReadOnlyCollection<int> readOnlyList = new ReadOnlyCollection<int>(modifiableList);// 使用只读列表foreach (var item in readOnlyList){Console.WriteLine(item);}// 任何试图修改 readOnlyList 的操作都会抛出异常// readOnlyList[0] = 10; // NotSupportedException// readOnlyList.Add(4); // NotSupportedException}
}
在上面的代码中,我们首先创建了一个包含三个元素的 List<int>
对象。然后我们将这个列表传递给 ReadOnlyCollection<int>
的构造函数,这样创建了一个只读的列表 readOnlyList
。这个只读列表包装了原始的列表,但是不提供任何修改该列表的方法。这意味着,尝试对 readOnlyList
进行任何修改都会导致运行时抛出异常。
如果需要返回符合 IReadOnlyList<T>
接口的只读列表,可以使用下面的方法:
public IReadOnlyList<T> GetReadOnlyList<T>(IList<T> list)
{return new ReadOnlyCollection<T>(list);
}
使用这种方式,你可以保持代码对返回类型的抽象,同时确保在任何情况下列表都是只读的。
三、数组
在C#中,数组(T[]
)是一个定长的数据结构,其大小在创建时被确定,并且不能被动态地增长或收缩。要想返回一个只读的数组,你可以返回数组的一个拷贝,客户代码可以自由地修改这个数组的副本,而不会影响原始数组。
以下是创建一个数组并返回其副本的示例代码:
public class ArrayExample
{private int[] _numbers;public ArrayExample(){_numbers = new[] {1, 2, 3, 4, 5}; // 初始化数组}public int[] GetNumbers(){// 返回原始数组的一个副本return (int[])_numbers.Clone();}
}
在这个例子中,GetNumbers
方法使用 Clone
方法来创建 _numbers
数组的一个完整拷贝,并将其返回。在这种情况下,调用者可以对返回的数组副本进行任何操作,而不会影响原始数组。
请注意,这种方法只适用于数组包含的是值类型(比如 int
, double
, char
等)或不可变的引用类型(比如 string
)。如果数组包含可变的引用类型,那么即使返回数组的副本,数组内部的对象仍然是可以被修改的。在这种情况下,你可能需要进行更深层次的拷贝(深拷贝),例如拷贝数组中每个对象的副本而不仅仅是引用。
如果你想要确保原始数组不能被修改,你还可以使用 Array.AsReadOnly
方法将数组转换为 ReadOnlyCollection<T>
,但是请注意这个方法不会返回数组类型,而是返回实现了IReadOnlyList<T>
和 IReadOnlyCollection<T>
接口的只读集合。
public ReadOnlyCollection<int> GetReadOnlyNumbers()
{// 返回只读集合封装的原始数组return Array.AsReadOnly(_numbers);
}
使用上述方法,用户可以访问原始数组的元素,但不能修改集合。这是一个返回原始数组只读视图的好方法,但请注意调用者得到的返回类型不是数组本身,而是封装数组的 ReadOnlyCollection<T>
对象。
相关文章:
C#中让字典、列表、数组作为只读的方法参考
一、字典 在 C# 中,可以通过使用 ReadOnlyDictionary<TKey, TValue> 类或者是通过调用普通字典的 .AsReadOnly() 方法来创建一个只读的字典。ReadOnlyDictionary 不允许修改字典,任何试图改变字典的操作都会抛出 NotSupportedException。 以下是使…...
深入理解 React 中的 children props 和 render props
深入理解 React 中的 children props 和 render props 在 React 中,children props 和 render props 是两种常见的组件复用模式,它们都可以帮助我们更好地组织和复用组件代码。虽然它们的实现方式有所不同,但都能够有效地实现组件之间的数据…...

前端日期组件layui使用,月模式
初学前端,实战总结 概要 有一个日期组件,我的谷歌浏览器选完日期后,偶尔获取不到最新数据,有一个客户,是经常出不来数据。 日期组件是Wdate:调用的方法是WdatePicker onpicking,代码片段如下…...

Rust编程(四)PackageCrateModule
这一部分的中文教程/文档都很混乱,翻译也五花八门,所以我建议直接看英文官方文档,对于一些名词不要进行翻译,翻译只会让事情更混乱,本篇从实战和实际需求出发,讲解几个名称的关系。 Module & Crate & Package & Workspace 英文中的意思: Cargo:货物 Crate:…...

命名空间【C++】(超详细)
文章目录 命名空间的概念命名空间的定义命名空间定义的位置作用域每一个命名空间都是一个独立的域作用域符:: 编译器找一个变量/函数等的定义,寻找域的顺序为什么要有命名空间?1.解决库与程序员定义的同名的重定义问题2.解决程序员…...

OceanBase OBCA 数据库认证专员考证视频
培训概述 OceanBase 认证是 OceanBase 官方推出的唯一人才能力认证体系,代表了阿里巴巴及蚂蚁集团官方对考生关于 OceanBase 技术能力的认可,旨在帮助考生更好地学习 OceanBase 数据库产品,早日融入 OceanBase 技术生态体系,通过由…...

卷积神经网络(CNN)——基础知识整理
文章目录 1、卷积神经网络 2、图片格式 3、图片卷积运算 4、Kernel 与 Feature Map 5、padding/边缘填充 6、Stride/步长 7、pooling/池化 8、shape 9、epoch、batch、Batch Size、step 10、神经网络 11、激活函数 1、卷积神经网络 既然叫卷积神经网络,这里面首先是…...
2024四川省赛“信息安全管理与评估“--网络事件响应--应急响应(高职组)
2024四川省赛“信息安全管理与评估“(高职组)任务书 2024四川省赛“信息安全管理与评估“任务书第一阶段竞赛项目试题第二阶段竞赛项目试题任务 1 应急响应(40分)第三阶段竞赛项目试题2024四川省赛“信息安全管理与评估“任务书 第一阶段竞赛项目试题 先略 第二阶段竞赛…...

Java类与对象:从概念到实践的全景解析!
个人主页:秋风起,再归来~ 文章专栏:javaSE的修炼之路 个人格言:悟已往之不谏,知来者犹可追 克心守己,律己则安! 1、类的定义格式 在java中定义类时需要用到…...
MySQL与SQLite区别
MySQL和SQLite都是关系型数据库管理系统(RDBMS),它们都使用SQL(结构化查询语言)作为标准查询语言。然而,尽管它们共享许多共同点,但它们在语法、功能、性能和存储机制方面存在一些差异。 以下是…...
【社会救助管理系统】主要设计及拟采用的技术方案
主要设计及拟采用的技术方案 1. 主要设计(1)系统架构设计(2)功能设计(3)安全性设计 2. 设计思想(1)系统架构设计思想(2)功能设计思想(3࿰…...

视频素材库哪个软件好?这8个高清无版权的素材网推荐
小伙伴们在制作短视频的时候,是不是为找素材发愁呢?一个高质量的无水印视频对创作者的帮助太大了,而且还需要无版权可商用的,那究竟有没有这样的网站呢?今天我来告诉大家。 1,蛙学府(中国&…...

GEE23:基于植被物候实现农作物分类
地物分类 1. 写在前面2. 北京作物分类 1. 写在前面 今天分享一个有意思的文章,用于进行农作物分类。文章提出了一个灵活的物候辅助监督水稻(PSPR)制图框架。主要是通过提取植被物候,并自动对物候数据进行采样,获得足够多的样本点,…...
一些常见的Docker问题和答案
什么是Docker?它的主要功能是什么? Docker是一种开源的容器化平台,用于构建、部署和运行应用程序。它的主要功能包括:快速构建、分发和运行应用程序的容器化环境,实现应用程序的可移植性和可扩展性。 Docker和虚拟机…...

Web CSS笔记2
目录 1、背景 ①、背景图片(image) ②、背景平铺(repeat) ③、背景位置(position) ④、背景附着(attachment) ⑤、背景透明(CSS3) ⑥、背景图片缩放大小(size): ⑦、背景简写 2、标签显…...
SpringBoot -- 整合SpringMVC
SpringBoot已经替我们整合了许多框架并进行了默认的配置,我们只需要在依赖中导入spring-boot-starter-web,就可以直接使用SpringMVC以及web场景下的已经整合好的功能。但SpringBoot的默认配置可能无法满足我们所有的需求,那么我们怎么进行自定…...

C语言操作符详细讲解
前言 本次博客一定会让刚刚学习C语言小白有所收获 本次操作符讲解不仅分类还会有代码示例 好好看 好好学 花上几分钟就可以避免许多坑 1 操作符的基本使用 1.1操作符的分类 按功能分 算术操作符: 、- 、* 、/ 、% 移位操作符: >> << 位操作符…...

Godot 学习笔记(5):国际化多语言翻译,包含常用10种语言机翻!
文章目录 前言国际化翻译Api选择小牛测试 语言选择代码逻辑实体对象翻译帮助类导出模板读取文件翻译测试多语言测试 综合翻译文件准备测试代码测试结果 完整代码实体类翻译帮助类网络帮助类 最终效果翻译前翻译中翻译后 总结 前言 为了面向更大的市场,国际化是肯定…...
服务器大请求体问题定位
背景 整个系统,分位微服务A、微服务B,A在调用B的过程中,报400BadRequest,问题定位到修复后,如何发送一个同样的请求进行验证 解决过程 1、查询A服务的日志,发现在调用B的过程中报错400BadRequest,并且请求体非常大300多KB 2、查看B服务的日志,发现请求没有进来 3、发…...

Vue指令之v-model
调了半天没反应,结果是没引用Vue,我是伞兵。 v-model的作用是将视图与数据双向绑定。一般情况下,Vue是数据驱动的,即数据发生改变后网页就会刷新一次,更改对应的网页内容,即数据单向绑定了网页内容。而使用…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...