I saw some code in this project that got my attention.
There is a simple method that calls AsReadOnly on a List. Instead of doing something with the ReadOnlyCollection the method returns it immediately and implicitly casts it into an IEnumerable.
What is the point of using AsReadOnly if you only need an Enumerable?
Would AsEnumerable be a better option?
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?
The point is that AsReadOnly
ensures that a low-trust hostile or buggy caller cannot cast back to a mutable collection.
Would
AsEnumerable
be a better option?
No. Try this:
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;
And now we have changed list[0]
.
But AsReadOnly
prevents this, as the read-only wrapper cannot be cast back to List<int>
.
Remember, AsEnumerable
is just a visually nicer way to write a cast, and casts that are reference conversions are reference conversions. The reference is not changed and it can be changed back to its actual type!
Of course, a hostile or buggy caller that has full trust can arbitrarily break the safety system, because full trust means full trust. A read only collection maintains a reference to the original collection, and that reference can be retrieved via reflection.
Also, remember that read-only means read-only, not unchanging. A read-only wrapper around a mutable collection can still be observed to change; you just cannot change it via the read-only wrapper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With