c# - 如果您最终将其转换为 IEnumerable,AsReadOnly 是否有意义?
问题描述
我在这个项目中看到了一些引起我注意的代码。
有一个简单的方法可以在 List 上调用 AsReadOnly。该方法不使用 ReadOnlyCollection 执行某些操作,而是立即返回它并隐式地将其转换为 IEnumerable。
如果您只需要一个 Enumerable,那么使用 AsReadOnly 有什么意义?
AsEnumerable 会是更好的选择吗?
private List<PaymentMethod> _paymentMethods = new List<PaymentMethod>();
public IEnumerable<PaymentMethod> PaymentMethods =>
_paymentMethods.AsReadOnly();
解决方案
AsReadOnly
如果您只需要一个可枚举的,那么使用有什么意义?
关键是AsReadOnly
确保低信任的敌对或错误的调用者不能转换回可变集合。
会
AsEnumerable
是更好的选择吗?
不,试试这个:
List<int> list = new List<int>{ 10, 20, 30 };
...
IEnumerable<int> seq = list.AsEnumerable();
// Or (IEnumerable<int>)list, or whatever.
...
List<int> list2 = (List<int>)seq;
list2[0] = 40;
而现在我们已经改变了list[0]
。
但是AsReadOnly
可以防止这种情况,因为只读包装器不能被强制转换回List<int>
.
请记住,AsEnumerable
这只是编写强制转换的一种视觉上更好的方式,并且作为引用转换的强制转换是引用转换。引用没有改变,它可以改回它的实际类型!
当然,具有完全信任的敌对或错误的调用者可以任意破坏安全系统,因为完全信任意味着完全信任。只读集合维护对原始集合的引用,并且可以通过反射检索该引用。
另外,请记住,只读意味着只读,而不是不变。仍然可以观察到围绕可变集合的只读包装器发生了变化;您只是无法通过只读包装器更改它。
推荐阅读
- c++ - C++ 部分特化友元声明——模板矩阵类
- python - 无法通过 anaconda 提示打开 jupyter notebook
- sharepoint - 根据文本字段在 Sharepoint 中设置下拉菜单的值
- excel - 在循环中复制范围内的非空白行
- python - Timeit.timeit 方法。哪种方式是正确的:内部还是外部?
- google-chrome-devtools - Chrome DevTools 远程调试器以不同方式显示颜色
- c - 为什么使用 %u 时我的 char 的二进制值会发生变化?
- ruby-on-rails - PG 搜索未返回预期记录
- asp.net-core - 身份服务器 4 和身份服务器 5 之间的区别
- react-native - 在 SVG 大小中使用双精度值可在 React Native 上提供视图切割