给出这些基类和接口
public abstract class Statistic : Entity, IStatistic
{
protected abstract IStatisticsRepository<IStatistic> Repository {get;}
...
public class AverageCheckTime : Statistic
...
public interface IStatisticsRepository<T> : IRepository<T> where T : IStatistic
...
public interface IAverageCheckTimeRepository : IStatisticsRepository<AverageCheckTime>
...
public class AverageCheckTimeRepository : StatisticRepository<AverageCheckTime>, IAverageCheckTimeRepository
...
public class RepositoryFactory
{
public static IAverageQueueTimeRepository AverageQueueTimeRepository
{
get { return CurrentServiceLocator.GetInstance<IAverageQueueTimeRepository>(); }
}
为什么AverageCheckTime的实现会抛出无效的强制转换异常:
protected override IStatisticsRepository<IStatistic> Repository
{
get { return (IStatisticsRepository<IStatistic>)RepositoryFactory.AverageCheckTimeRepository; }
}
如何将IAverageCheckTimeRepository
的实例转换为IStatisticsRepository<IStatistic>
,我认为它已经存在?
好的,我已经做出了这些改变......这让我想知道我是否已经首先使用仿制药进入顶层
public interface IStatisticsHelper
{
void GenerateStatistics();
List<IStatistic> BuildReport();
}
...
public interface IStatisticsRepository<T> : IRepository<T>, IStatisticsHelper where T : IStatistic
{
}
...
public abstract class Statistic : Entity, IStatistic
{
protected abstract IStatisticsHelper Repository { get; }
...
public class AverageCheckTime : Statistic
{
protected override IStatisticsHelper Repository
{
get { return RepositoryFactory.AverageCheckTimeRepository; }
}
答案 0 :(得分:5)
不,C#3不支持通用差异。 C#4有,但您必须声明IStatisticsRepository
中T
是协变的:
public interface IStatististicsRepository<out T> : IRepository<T>
where T : IStastistic
方差通常 - 它取决于泛型类型参数的使用方式。 C#4支持作为引用类型的类型参数的协方差和逆变,但仅当涉及的泛型类型是接口或委托时,并且仅当在接口/委托中以适当的方式使用type参数时才支持协方差。
如果没有看到IRepository<T>
的声明,我们无法判断它是否安全。例如,如果IRepository<T>
包含这样的方法:
void Save(string id, T value);
然后它不会安全,因为你可以写:
IStatisticsRepository<IStatistic> repo = RepositoryFactory.AverageCheckTimeRepository;
IStatistic foo = new SomeOtherStastisticType();
repo.Save("Foo", foo);
这会尝试在SomeOtherStatisticType
中保存AverageCheckTimeRepository
值,这违反了类型安全性。如果类型T
的值仅出现在接口之外,那么在T
中使接口协变是唯一安全的。 (关于这意味着什么,有一些皱纹,请注意......)
有关此问题的更多信息,请参阅Eric Lippert的blog series on the topic。