【发布时间】:2020-01-30 08:05:55
【问题描述】:
我需要帮助解决我的代码中的协变情况。
让我用例子来说明情况:
abstract class BaseSource { }
abstract class BaseTarget { }
class SourceEntityA : BaseSource { }
class TargetEntityB : BaseTarget { }
interface IEntityMapper { }
interface IEntityMapper<in TSource, out TTarget>: IEntityMapper
{
TTarget Map(TSource entity);
}
abstract class BaseEntityMap<TSource, TTarget> : IEntityMapper<TSource, TTarget>, IEntityMapper
{
public abstract TTarget Map(TSource entity);
}
class OrderEntityMapper : BaseEntityMap<SourceEntityA, TargetEntityB>
{
public override TargetEntityB Map(SourceEntityA entity)
{
//do some map stuff
return null;
}
}
class GoodsEntityMapper : BaseEntityMap<SourceEntityC, TargetEntityD>
{
public override TargetEntityD Map(SourceEntityC entity)
{
//do some map stuff
return null;
}
}
class Workflow
{
IDictionary<Type, IEntityMapper> MappersMap = new Dictionary<Type, IEntityMapper>();
public MappingArchestrator()
{
MappersMap.Add(typeof(SourceEntityA), new OrderEntityMapper());
MappersMap.Add(typeof(SourceEntityC), new GoodsEntityMapper());
//....more mappers
}
private IEnumerable<BaseSource> GetSourceEntities()
{
//return source data
return null;
}
public void Execute()
{
foreach (var m in MappersMap.Keys)
{
var mapper = MappersMap[m];
var entities = GetSourceEntities();
foreach (var entity in entities)
{
//Need to handle this situations with correct covariations.
var target = (IEntityMapper<BaseSource, BaseTarget>mapper).Map(entity);
//.... code continues
}
}
}
}
很快,我需要不同类型映射器的字典,并在通用代码中使用它们的 Execute 方法来处理工作流。
您能否指导我编写更好的代码或修复现有解决方案?有可能吗?
或者我必须在这里忘记泛型并在 Map 方法中使用 BaseClasses 并将它们转换为我需要的类型。
类似的东西
abstract class BaseEntityMap : IEntityMapper
{
public abstract BaseTarget Map(BaseSource entity);
}
谢谢
【问题讨论】:
-
你对泛型和接口的使用对我来说看起来很教科书。你为什么不满意?
-
问题是,我不能将 IEntityMapper 的映射器转换为 var target = (IEntityMapper
mapper).Map(entity);。我需要转换它,因为我需要通用方法 Map 来执行实体映射。是不是更清楚了? -
实现
IEntityMapper<BaseSource,BaseTarget>的类承诺将继承自BaseSource的任何类型的TSource作为输入。但是GoodsEntityMapper和OrderEntityMapper都做不到。
标签: c# .net generics covariance