具有逆变接口作为成员属性的协变接口



我有一个接口,它为任何IFoo定义了读取器和编写器。

public interface IFoobarStore<out E>
where E : class, IFoobar
{
IFoobarReader<E> GetReader();
IFoobarWriter<E> GetWriter();
}

IFoobarStore 是协变的。IFoobarStore 与任何派生的 IFoo 交互。因此,任何更多派生的 IFoo 都应该可以分配给派生的 IFoo 类型参数。

// DerivedFoobityStore.cs
public sealed class DerivedFoobityStore
: IFoobarStore<MyFoobity>
{
// implementation follows
}

如果IFoobarStore被定义为IFoobarStore<E>变体而不是IFoobarStore<out E>,则会产生编译器错误CS0266。

IFoobarStore<IFoo> myGenericStore = new DerivedFoobityStore();

读取器也被定义为协变。它应该允许从某处读取派生的 IFoo 对象。

using System.Collections.Generic;
public interface IFoobarReader<out E>
where E : class, IFoo
{
IEnumerable<E> GetAll();
IEnumerable<E> GetBy(params object[] vars);
E GetSingle(object uniqueIdentifier);
}

IFoobarWriter 公开用于任何 IFoo 上的标准 CRUD 操作的成员。

public interface IFoobarWriter<in E>
where E : class, IFoo
{
void Add(E foo);
int Delete(E foo);
E Update(E foo);
}

由于每个操作都有一个类型 E 的参数(从 IFoo 派生的任何类(,因此必须将 IFoobarWriter 标记为逆变。

当我编译代码时,我收到此错误:

Invalid variance: The type parameter 'E' must be contravariantly valid on 'IFoobarStore<E>.GetWriter()'. 'E' is covariant.

如何更好地重构此代码以使其成功编译?

目前,我通过重构IFoobarWriter来处理对象而不是IFoo来解决这个问题。

public interface IFoobarWriter<out E>
where E : class, IFoo
{
void Add(object foo);
int Delete(object foo);
object Update(object foo);
}

这使得IFoobarWriter的基本前提过时了。

解决方案是删除 E 作为可接受的参数,例如 IFoobarWriter 的成员方法。

public interface IFoobarWriter<out E>
where E : class, IFoo
{
void Add(IFoo foo);
int Delete(IFoo foo);
object Update(IFoo foo);
}

通过让"添加"、"删除"和"更新"接受IFoo它们有效地限制了它们可以处理的类型(而不是将参数设置为object(,足以满足某些业务需求。

让 IFoobarWriter 的类型参数 E 保持协变允许它仍然是 IFoobarStore 接口的一部分。

相关内容

  • 没有找到相关文章

最新更新