使用自定义集合类时接口不再起作用
我创建了一个类 MonitoredCollection
,它基本上封装/模仿 List,但允许我在某些调用上触发事件。
但是现在,只要有一个采用 MonitoredCollection 的参数,其中 T 是一个接口,我就无法再传递一个 MonitoredCollection
其中 T 是实现该接口的类,就像我可以使用一个列表
。
我一直认为接口是一种语言“功能”,因此我不需要再实现任何东西来支持这一点,那么我错过了什么?
编辑:抱歉,我在这个问题上犯了一个错误,因为 João 正确地指出 List 在这种情况下从未起作用,所以问题就是没有这个!
I have created a class, MonitoredCollection<T>
, that basically encapsulates/mimics List but allows me to fire events on certain calls.
Now however, whereever there is a parameter that takes a MonitoredCollection, where T is an Interface, I can no longer pass a MonitoredCollection<T>
where T is a class that implements that interface, like I could with a List
.
I always thought that interfaces were a language 'feature' and therefore I don't need to implement anything more to support this, so what have I missed?
EDIT: Sorry, I made a mistake in that question, as João correctly pointed out List never worked in this instance so the question is as it stands without that!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设您有一个
MonitoredCollection
实例,并且您希望将其视为MonitoredCollection
实例,其中SomeObject
实际上实现了ISomeInterface
。这不会对从集合中检索项目产生任何问题,因为SomeObject
类型的对象可以转换为接口类型ISomeInterface
。但是,对于集合中修改集合的所有方法(例如为索引分配新值或将新项目插入集合中的方法),此转换会产生一整套问题。我假设您的
MonitoredCollection
实例具有诸如Add(SomeObject obj)
之类的方法,该方法会将新对象插入到集合中。转换后,此方法的签名将是Add(ISomeInterface obj)
。这似乎是有道理的,但并非所有ISomeInterface
对象都必然是SomeObject
实例。由于转换后的对象将允许对原始对象不允许的集合进行操作,因此运行时将不允许此转换。 C# 4.0 引入了协变和逆变来明确说明什么对于这种类型的强制转换是有效的,您可以研究它们以尝试解决此问题。但是,您实际上只能幸运地获得集合的只读版本(想想
List.AsReadOnly()
)。Suppose you have a
MonitoredCollection<SomeObject>
instance, and you want to treat it as aMonitoredCollection<ISomeInterface>
instance whereSomeObject
does in fact implementISomeInterface
. This does not create any problems for retrieving items from the collection, since object of typeSomeObject
can be converted to the interface typeISomeInterface
.However, for all the methods on your collection which modify the collection, such as those that assign a new value to an index, or insert a new item into the collection, this cast has created a whole suite of issues. I'd assume your
MonitoredCollection<SomeObject>
instance would have a method such asAdd(SomeObject obj)
, which would insert a new object into the collection. After the cast, the signature on this method would beAdd(ISomeInterface obj)
. This seems to make sense, but not allISomeInterface
objects are NECESSARILYSomeObject
instances.Because the casted object will allow operations on the collection that the original object wouldn't allow, the runtime won't allow this cast. C# 4.0 introduced covariance and contravariance to explicitly state what is valid for casts of this type, you can look into them for trying to solve this issue. However, you're really only going to have luck with a read only version of your collection (think
List<T>.AsReadOnly()
).不幸的是,你也不能用列表来做到这一点。编译器仍然无法转换类型。您需要使用通用方法。参见下面的代码:
Unfortunately, you can't do that with a list either. The compiler still cannot convert the types. You need to use a generic method. See code below: