![](/img/trans.png)
[英]Using interface with contravariant type as a return type of a method in an interface with covariant type
[英]Covariant interface with contravariant interface as member property
我有一个接口,可以为任何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);
}
通过使Add,Delete和Update接受IFoo
它们可以有效地限制它们可以处理的类型(与将参数设置为object
),足以满足某些业务需求。
使IFoobarWriter的类型参数E保持协变,使其可以保留为IFoobarStore接口的一部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.