我有以下代码片段:
interface IRepositoryBase<BackupType> where BackupType : IBackup {
IEnumerable<BackupType> Backups { get; set; }
void Delete(BackupType backup);
BackupType GetOrCreateBackup(IFileSource source);
}
interface IRepository : IRepositoryBase<IBackup> {
}
interface IRepository<BackupType> : IRepository, IRepositoryBase<BackupType> where BackupType : IBackup {
}
基本上我的要求是我希望能够将任何 IRepository
不幸的是,编译器在代码中给出了以下错误:
IRepository<BackupType> cannot implement both IRepositoryBase<IBackup> and IRepositoryBase<BackupType> because they may unify for some type parameter substitutions
所以我再试一次其他一些代码来消除此错误(IRepositoryBase<>接口消失了):
interface IRepository {
IEnumerable<IBackup> Backups { get; set; }
void Delete(IBackup backup);
IBackup GetOrCreateBackup(IFileSource source);
}
interface IRepository<BackupType> : IRepository where BackupType : IBackup {
new IEnumerable<BackupType> Backups { get; set; }
void Delete(BackupType backup);
new BackupType GetOrCreateBackup(IFileSource source);
}
现在我有这些丑陋的"新"在那里。此外,在实现 IRepository
有人可以告诉我如何正确地做到这一点吗?:)
如果你看看Microsoft是如何实现的List<T>
你会发现它们没有继承接口。 您可以将List<T>
视为IList
和IList<T>
的唯一原因是List<T>
同时实现了它们。
您可能想要的是显式实现非泛型接口。 下面是隐式实现和显式实现之间的区别:
// Implicit
public IEnumerable<TapeBackup> Types { get; set; }
// Explicit
IEnumerable<IBackup> IRepository.Types { get; set; }
显式接口实现隐藏在程序集元数据中,除非您首先将实例强制转换为适当的接口类型,否则无法访问。 您只需将显式实现包装并调用隐式实现,因为这些类型很可能是兼容的。
但是我认为您无法实现仅为两个接口实现一次成员的目标。
这是你想要实现的吗?
internal class BackupType : IBackup { }
internal interface IFileSource { }
internal interface IBackup { }
interface IRepository<TBackup> where TBackup : IBackup
{
IEnumerable<TBackup> Backups { get; set; }
void Delete(TBackup backup);
TBackup GetOrCreateBackup(IFileSource source);
}
interface IRepository : IRepository<IBackup> { }
interface IRepositoryBackupType : IRepository<BackupType> { }
class RepositoryBackupType:IRepository,IRepositoryBackupType
{
... (implementation of both interfaces)
}
但是,如果您将拥有一个实现这两个接口的类,则必须显式实现它们,因为我认为类型系统无法推断底层集合的转换。
List
如果你选择:
interface IRepositoryBase<TBackup> where TBackup : IBackup
{
IEnumerable<TBackup> Backups { get; set; }
void Delete(TBackup backup);
TBackup GetOrCreateBackup(IFileSource source);
}
interface IRepository
{
IEnumerable<IBackup> Backups { get; set; }
void Delete(IBackup backup);
IBackup GetOrCreateBackup(IFileSource source);
}
interface IRepository<TBackup> : IRepositoryBase<TBackup>, IRepository where TBackup : IBackup
{
}
编译器不会抱怨。
您仍然必须实现六个成员,而不是每次实现三个成员,其中一些成员通过显式接口实现。我没有解决方案。
当您实现泛型IEnumerable<>
并且必须提供两种GetEnumerator
方法时也是如此,因为您还继承了非泛型IEnumerable
。