IList在c#中使用协变和逆变,这可能吗?
这可能吗? (我没有 vs. 2010,所以我无法自己尝试,抱歉)
public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
public IEnumerator<TOutput> GetEnumerator();
public void Add(TInput item);
}
public interface IList<T> : IComplexList<T, T>
{
}
如果我做对了,您可以使用它在同一接口中实际实现协变和逆变。
would this be possible? (I don't have vs. 2010, so I can't try it myself, sorry)
public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
public IEnumerator<TOutput> GetEnumerator();
public void Add(TInput item);
}
public interface IList<T> : IComplexList<T, T>
{
}
If I get it right, you could use this to actually implement covariance and contravariance in the same interface.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,由于现有的
IList
类型,您的问题有点令人困惑。 但是,以下确实可以编译:您甚至可以更改它以扩展
IEnumerable
:索引器很棘手,因为您需要涉及不同的类型。 您可以这样做:
然后将索引器放入
ISimpleList
而不是当然...但这并不能让您以不同方式使用
ISimpleList
,因为您基本上强制 TInput=TOutput。另一种方法是将输入与输出分开:
然后您可以编写:
对于
IReadableList
反之亦然。 换句话说,您允许每一方单独存在差异,但永远不会同时获得两侧的差异。Well, your question is slightly confusing because of the existing
IList<T>
type. However, the following does compile:You can even change it to extend
IEnumerable<TOutput>
:The indexer is tricky, because you'd want different types involved. You could do:
and then put the indexer into
ISimpleList<T>
instead of course...That doesn't let you use
ISimpleList<T>
variantly though, because you've basically forced TInput=TOutput.An alternative approach is to separate out the input from the output:
Then you could write:
and vice versa for
IReadableList
. In other words, you allow variance for each side individually, but you never get variance for the two sides together.不,你不能。 在您的示例中
IList
是不变的。IList
需要将in
/out
声明为协变/逆变。 仅通过继承一些协变的接口是不可能做到这一点的。No, you can't. In your example
IList<T>
is invariant.IList<T>
would require to declarein
/out
to be covariant/contravariant. It's not possible to do that just by inheriting some interface that is covariant.如果读写属性的实现也被视为只读属性的实现,则可以通过从 IReadableList(of Out T) 和 IAddableList(的 T)。 假设这些接口在定义之前仅包含 IList(Of T) 中存在的成员,则实现 IList(Of T) 的代码将自动实现这些其他成员。 不幸的是,要使 IReadableList 协变,它必须具有只读索引器属性; IList 中读写属性的实现无法替代。 因此,让 IList(Of T) 从可用的 IReadableList(Of Out T) 继承将破坏 IList(Of T) 的所有实现。
If an implementation of a read-write property were also considered an implementation of a read-only property, one could add a useful form of List covariance and contravariance by having IList(of T) derive from IReadableList(of Out T) and IAddableList(of In T). Provided that those interfaces simply included members that were present in IList(Of T) before they were defined, code which implemented IList(Of T) would automatically implement those other members. Unfortunately, for IReadableList to be covariant, it would have to have a read-only indexer property; the implementation of the read-write property in IList could not be substituted. Having IList(Of T) inherit from a usable IReadableList(Of Out T) would thus break all implementations of IList(Of T).