C#3.0铸造的接口泛型类型
问题描述:
鉴于这些基类和接口C#3.0铸造的接口泛型类型
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>
我认为它已经是?
OK,我做了这些改变......这使我想知道如果我已经在上面与仿制药摆在首位
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; }
}
答
不,C#3不支持通用方差。 C#4,但你必须声明IStatisticsRepository
是协变的T
:
public interface IStatististicsRepository<out T> : IRepository<T>
where T : IStastistic
差异不是一般安全- 这取决于泛型类型参数是如何使用的。只有当涉及的泛型类型是接口或委托,并且只有在接口/委托中以适当的方式使用类型参数时,C#4才支持引用类型的类型参数的协方差和反变量。
没有看到IRepository<T>
的声明,我们无法判断它是否安全。例如,如果IRepository<T>
包含这样的方法:
void Save(string id, T value);
那么不会是安全的,因为你可以写:
IStatisticsRepository<IStatistic> repo = RepositoryFactory.AverageCheckTimeRepository;
IStatistic foo = new SomeOtherStastisticType();
repo.Save("Foo", foo);
,这将是试图拯救AverageCheckTimeRepository
中的SomeOtherStatisticType
值,这违反了类型安全性。如果T
类型的值仅出现在接口“出”,那么仅在T
中使接口协变才是安全的。 (有一些皱纹正是这意味着什么,请记住你......)
欲了解更多信息,请参阅Eric Lippert的blog series on the topic。
你失去了一些东西,因为没有在那里我看到了'StatisticRepository'是'IStatisticRepository ' –
msarchet
作出编辑:公共接口IStatisticsRepository:IRepository 其中T:IStatistic –
@BobTodd:现在我们不'不知道'IRepository'看起来像...... –