请考虑此界面:
public interface IInitialiazableEntity<TRepository> where TRepository : class, IRepository
{
void Initialize(TRepository repository);
}
此类(摘录):
public class SomeFacade<TRepository> where TRepository : class, IRepository
{
public void Add<TEntity>(TEntity entity) where TEntity : AbstractEntity
{
try
{
if (entity is IInitialiazableEntity<TRepository>)
(entity as IInitialiazableEntity<TRepository>).Initialize(this.Repository);
}
catch (Exception ex)
{
this.Logger.Error(ex);
}
}
}
实体:
public class Student : AbstractEntity, IInitialiazableEntity<IRepository>
{
void Initialize(IRepository repository) { ... }
}
由于学生只有IInitialiazableEntity<IRepository>
且门面将有一个比基本IRepository
更专业的实际存储库(即它将是IMySpecialRepository : IRepository
),{{1 }} keyword意识到它可以强制转换is
并将其传递给实体的IMySpecialRepository
方法?或者如果没有,怎么做?
答案 0 :(得分:1)
假设您的实体属于Student类型,'is'将返回false;这是因为Student没有实现更具体的界面专业化。但是,您不需要转换为更具体的接口。这应该可以正常工作:
public class SomeFacade<TRepository> where TRepository : class, IRepository
{
public void Add<TEntity>(TEntity entity) where TEntity : AbstractEntity
{
try
{
if (entity is IInitialiazableEntity<IRepository>)
(entity as IInitialiazableEntity<IRepository>).Initialize(this.Repository);
}
catch (Exception ex)
{
this.Logger.Error(ex);
}
}
}
答案 1 :(得分:1)
目前,如果您有一个实例SomeFacade<IMySpecialRepository>
,代码将无效。
你有两种选择,一种是丹·布莱恩特提供的答案,另一种是使IInitialiazableEntity<TRepository>
逆变。
您的界面声明将变为(请注意泛型类型的in
):
public interface IInitialiazableEntity<in TRepository> where TRepository : class, IRepository
{
void Initialize(TRepository repository);
}
这将允许您is
检查和转换工作,因为IInitialiazableEntity<IRepository>
在使用逆变通用时可以转换为IInitialiazableEntity<IMySpecialRepository>
。
有关泛型中协方差和反演的更多信息,请参阅here。