这会是可能的吗? (我没有对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>
{
}
如果我得到它的权利,你可以使用它来真正实现在同一界面协方差和逆变。
不,你不能。 在您的示例IList<T>
是不变的。 IList<T>
将需要声明in
/ out
为协变/逆变。 这是不可能做到这一点只是继承了一些接口是协变的。
那么,你的问题是因为现有的稍显混乱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>
variantly不过,因为你已经基本上被迫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
。 换句话说,你允许每方方差分别,但你永远不会得到双方方差在一起。
如果读写属性的实现也被认为是一个只读属性的实现,人们可以通过具有的IList(Of T)已添加列表协变和逆变的有用的形式从IReadableList(出的T)和IAddableList(派生的在T)。 提供这些接口简单地包含该存在于的IList(Of T)已被定义之前,其实现的IList(OF T)将自动地执行这些其他成员代码成员。 不幸的是,IReadableList是协变,那就必须有一个只读的索引器属性; 在IList的读写性能的实现不能被取代。 因此具有的IList(OF T)从一个可用IReadableList(出T)继承将打破的IList(OF T)的所有实现。