6

这可能吗?(我没有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>
{
}

如果我做对了,您可以使用它在同一接口中实际实现协变和逆变。

4

3 回答 3

8

IList<T>好吧,由于现有类型,您的问题有点令人困惑。但是,以下内容编译:

public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
    IEnumerator<TOutput> GetEnumerator();
    void Add(TInput item);
}

public interface ISimpleList<T> : IComplexList<T, T>
{
}

您甚至可以将其更改为扩展IEnumerable<TOutput>

public interface IComplexList<out TOutput, in TInput>
    : IEnumerable<TOutput>
    where TOutput : TInput
{        
    void Add(TInput item);
}

public interface ISimpleList<T> : IComplexList<T, T>
{
}

索引器很棘手,因为您需要涉及不同的类型。你可以这样做:

TOutput Get(int index);
void Set(int index, TInput item);

然后将索引器放入ISimpleList<T>而不是...

但是,这并不允许您使用ISimpleList<T>变体,因为您基本上已经强制 TInput=TOutput。

另一种方法是将输入与输出分开:

public interface IReadableList<out T> : IEnumerable<T>
{
    T Get(int index);
}

public interface IWritableList<in T>
{
    void Add(T item);
    void Set(int index, T item);
}

 public interface IMyList<T> : IReadableList<T>, IWritableList<T> {}

然后你可以写:

public void Foo(IWritableList<string> x) { ... }

IMyList<object> objects = new MyList<object>();
Foo(objects);

反之亦然IReadableList。换句话说,你允许每一边单独出现差异,但你永远不会得到两侧的差异。

于 2009-08-11T08:49:35.227 回答
5

不,你不能。在您的示例IList<T>中是不变的。IList<T>将需要声明in/out是协变/逆变的。仅仅通过继承一些协变的接口是不可能的。

于 2009-08-11T08:45:58.953 回答
0

如果读写属性的实现也被视为只读属性的实现,则可以通过让 IList(of T) 从 IReadableList(of Out T) 和 IAddableList(在 T 中)。如果这些接口仅包含在定义之前存在于 IList(Of T) 中的成员,则实现 IList(Of T) 的代码将自动实现这些其他成员。不幸的是,要使 IReadableList 成为协变的,它必须具有只读索引器属性;IList 中读写属性的实现无法替代。因此,让 IList(Of T) 从可用的 IReadableList(Of Out T) 继承会破坏 IList(Of T) 的所有实现。

于 2010-12-23T17:22:18.717 回答