我遇到了一些接口和共同/逆变问题,我遇到了一些问题。想象一下如下的结构(原谅任何明显的错误,我现在都在移动)
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',它就可以工作。如果我删除了Reader,那么如果我将T设为'out'就行。我需要做两件事,但显然不能!
我是真的很蠢还是我想要的不可能?谢谢!
答案 0 :(得分:0)
T
在IMapper
中是逆变的,但在IProfile
和IDelimitedFileReader
中是协变的。协变和逆变的定义是不变,这意味着T不允许任何类型的方差;类似于IList。您当前的设置无效。
如果你在所有接口中声明所需的方差,应该明确这个问题(正如你应该做的那样,否则你会得到神秘的错误消息,因为编译器不能做得更好):
interface IDelimitedFileReader<out T> { /*...*/ }
interface IMapper<in T> { /*...*/ }
interface IProfile<out T> { /*...*/ } //at first glance it looks covariant
如果你试图编译它,编译器会给你一个错误的错误。
如果您在T
:IProfile
中声明interface IProfile<T> { //... }
不变,那么错误就会消失,代码应该编译,但是你会遇到一个不变的界面。