.NET 中如何定义泛型接口统一不同入参的GetOpenPositions方法签名
最优解决方案:使用带约束的泛型接口
你之前实现报错的原因是C#接口实现要求参数签名完全一致,接口约定的入参是IEnumerable<OpenPositionBase>,实现类直接替换为子类集合类型属于类型不匹配,通过给接口加泛型约束就能完美解决:
// 定义带泛型约束的接口,T必须继承自公共基类OpenPositionBase public interface IPositionConverter<T> where T : OpenPositionBase { IEnumerable<Position> GetOpenPositions(IEnumerable<T> openPositions, uint ownerId, IEnumerable<agile_shared.RequestModel.OpenPosition> orgOpenPositionList); }
实现类只要指定对应的泛型参数即可,不需要修改原有业务逻辑:
public class AlliancePositionConverter : IPositionConverter<AllianceOpenPosition> { public IEnumerable<Position> GetOpenPositions(IEnumerable<AllianceOpenPosition> allianceOpenPositions, uint allianceId, IEnumerable<agile_shared.RequestModel.OpenPosition> orgOpenPositionList) { return allianceOpenPositions.Where(w => w.AllianceId == allianceId) .Select(s => new Position(orgOpenPositionList.FirstOrDefault(wh => wh.Id == s.OpenPositionId)) { Id = s.Id.ToString(), AgileRole = s.LeadRole.Name, AgileRoleRank=s.LeadRole.Rank }).ToList(); } }
同理其他两个实现类只需要把泛型参数替换为SquadOpenPosition、TribeOpenPosition即可,后续如果新增其他继承自OpenPositionBase的类型,只要新增对应实现类指定泛型参数就行,扩展性极强。
如果有统一调度所有Converter的需求,还可以搭配泛型协变实现多态调用:
// 给泛型参数加out关键字开启协变 public interface IPositionConverter<out T> where T : OpenPositionBase { IEnumerable<Position> GetOpenPositions(IEnumerable<OpenPositionBase> openPositions, uint ownerId, IEnumerable<agile_shared.RequestModel.OpenPosition> orgOpenPositionList); } // 实现类内部做类型安全转换 public class AlliancePositionConverter : IPositionConverter<AllianceOpenPosition> { public IEnumerable<Position> GetOpenPositions(IEnumerable<OpenPositionBase> openPositions, uint allianceId, IEnumerable<agile_shared.RequestModel.OpenPosition> orgOpenPositionList) { var allianceOpenPositions = openPositions.OfType<AllianceOpenPosition>(); return allianceOpenPositions.Where(w => w.AllianceId == allianceId) .Select(s => new Position(orgOpenPositionList.FirstOrDefault(wh => wh.Id == s.OpenPositionId)) { Id = s.Id.ToString(), AgileRole = s.LeadRole.Name, AgileRoleRank=s.LeadRole.Rank }).ToList(); } }
这种方案下你可以把所有Converter存入List<IPositionConverter<OpenPositionBase>>集合,实现动态匹配调用的需求。
内容的提问来源于stack exchange,提问作者Sándor Jankovics
相关产品推荐
相关产品推荐

