ReadOnlyCollection 有什么神奇之处吗
有了这段代码...
var b = new ReadOnlyCollection<int>(new[] { 2, 4, 2, 2 });
b[2] = 3;
我在第二行收到编译错误。我预计会出现运行时错误,因为 ReadOnlyCollection
实现 IList
并且 this[T]
在 中有一个设置器>IList
接口。
我尝试复制 ReadOnlyCollection 的功能,但从 this[T]
中删除 setter 是一个编译错误。
Having this code...
var b = new ReadOnlyCollection<int>(new[] { 2, 4, 2, 2 });
b[2] = 3;
I get a compile error at the second line. I would expect a runtime error since ReadOnlyCollection<T>
implements IList<T>
and the this[T]
have a setter in the IList<T>
interface.
I've tried to replicate the functionality of ReadOnlyCollection, but removing the setter from this[T]
is a compile error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
索引器是通过显式接口实现实现的,因此您只需如果您这样做,则能够访问它:
或者
当然,它会在执行时失败...
这完全是经过深思熟虑且有帮助的 - 这意味着当编译器知道它是一个
ReadOnlyCollection
,您无法使用不受支持的功能,从而帮助您避免执行时失败。不过,这是一个有趣且相对不寻常的步骤,有效隐式实现属性/索引器的一半,显式实现一半。
与我之前的想法相反,我相信 ReadOnlyCollection实际上显式地实现了整个索引器,但还提供了一个公共只读索引器。换句话说,它是这样的:
The indexer is implemented with explicit interface implementation, so you'll only be able to access it if you do:
or
Of course, it'll then fail at execution time...
This is entirely deliberate and helpful - it means that when the compiler knows it's a
ReadOnlyCollection
, the unsupported bits of functionality aren't available to you, helping to divert you away from execution time failure.It's an interesting and relatively unusual step though, effectively implementing one half of a property/indexer implicitly, and one half explicitly.
Contrary to my previous thoughts, I believe
ReadOnlyCollection<T>
actually implements the whole indexer explicitly, but also provides a public readonly indexer. In other words, it's something like this:它显式实现 IList.Items,这使其成为非公开的,并且您必须强制转换为接口才能实现其实现,并实现一个新的 this[...] 索引器,该索引器被使用,它只有一个获取访问器。
如果将集合转换为 IList,您的代码将编译,但会在运行时失败。
不幸的是,我不知道如何在 C# 中执行此操作,因为在 C# 中编写索引器涉及使用
this
关键字,并且您不能这样写:It implements IList.Items explicitly, which makes it non-public, and you'll have to cast to the interface to reach its implementation, and implements a new this[...] indexer, which is used instead, which only has a get-accessor.
If you cast the collection to IList, your code will compile, but will fail at runtime instead.
Unfortunately I don't know how to do this in C#, since writing an indexer in C# involves using the
this
keyword, and you can't write this:没有什么神奇之处,
ReadOnlyCollection
只是对其自己的索引器和实现IList
接口的索引器有不同的实现:如果您将列表转换为
IList
,您将收到运行时错误而不是编译错误:编辑:
要在您自己的类中实现索引器,请使用
this
关键字:There is no magic, the
ReadOnlyCollection
just have different implementations for it's own indexer and the indexer that implements theIList<T>
interface:If you cast your list to
IList<int>
, you will get a runtime error instead of the compilation error:Edit:
To implement the indexer in your own class, you use the
this
keyword: