不能在接口上同时使用协方差和逆变



我在接口和协变/逆变方面遇到了一些问题,我遇到了一些问题。想象一下像下面这样的结构(请原谅任何明显的错误,我现在在移动领域(

public interface IDelimitedFileReader<T>
{
      IEnumerable<T> Read(string file);
}
public interface IMapper<T> where T : IManifestItem
{
      MappedRecord Map(IEnumerable<T> items);
}
public interface IProfile<T> where T : IManifestItem
{
      IDelimitedFileReader<T> Reader { get; }
      IMapper<T> Mapper { get; }
}
public class ProfileImpl : IProfile<ManifestItemImpl>
{
           IDelimitedFileReader<ManifestItemImpl> Reader => new DelimitedFileReaderImpl<ManifestItemImpl>();
      IMapper<ManifestItemImpl> Mapper => new MapperImpl<ManifestItemImpl>();
}
public static class ProfileRetriever
{
     public static IProfile<IManifestItem> GetProfile()
     {
             return new ProfileImpl();
     }
}

但是,我的 GetProfile 方法抱怨返回类型不匹配。我相信这是因为 IProfile 接口需要协变和逆变 - 如果我删除接口和实现上的 Mapper 属性,并将 T 更改为 IProfile 中的"in",它可以工作。如果我删除阅读器,如果我使 T "出",它会起作用。我需要同时做这两件事,但显然不能!

我真的是愚蠢还是我想要的不可能?谢谢!

T

IMapper中是逆变的,但在IProfileIDelimitedFileReader中是协变的。某物协变和逆变的定义是不变的,这意味着 T 不允许任何类型方差;类似于IList。您当前的设置将不起作用。

如果您在所有接口中声明所需的方差,则应明确该问题(您应该这样做,否则您将收到神秘的错误消息,因为编译器无法做得更好(:

interface IDelimitedFileReader<out T> { /*...*/ }
interface IMapper<in T> { /*...*/ }
interface IProfile<out T> { /*...*/ } //at first glance it looks covariant

如果您尝试编译它,编译器会给您一个精确的错误。

如果你在IProfile中声明T不变的:interface IProfile<T> { //... }那么错误就会消失,代码应该编译,但你坚持使用不变的接口。

最新更新