如果您最终将 AsReadOnly 投射到 IEnumerable 中,它是否有意义?

Does AsReadOnly make sense if you cast it in an IEnumerable eventually?

我在 this 项目中看到一些代码引起了我的注意。

有一个简单的方法可以调用 List 上的 AsReadOnly。而不是使用 ReadOnlyCollection 方法 returns 它立即隐式地将其转换为 IEnumerable.

如果您只需要一个 Enumerable,那么使用 AsReadOnly 有什么意义?

A​​sEnumerable 会是更好的选择吗?

private List<PaymentMethod> _paymentMethods = new List<PaymentMethod>();

public IEnumerable<PaymentMethod> PaymentMethods => 
        _paymentMethods.AsReadOnly();

What is the point of using AsReadOnly if you only need an enumerable?

重点是 AsReadOnly 确保低信任度的恶意或错误调用者无法转换回可变集合。

Would AsEnumerable be a better option?

没有。试试这个:

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 只是一种视觉上更好的编写转换的方式,作为引用转换的转换是 引用转换。引用未更改,可以更改回其实际类型!

当然,完全信任的恶意调用者或有漏洞的调用者可以任意破坏安全系统,因为完全信任意味着 完全信任。只读集合维护对原始集合的引用,并且可以通过反射检索该引用。

此外,请记住只读意味着只读,而不是不变。围绕可变集合的只读包装器仍然可以 observed 进行更改;您只是无法通过只读包装器更改它