如何定义ICollection的扩展方法<T>其中T:IMyInterface而不在方法定义中指定T.

Noe*_*oel 2 c# generics extension-methods automapper

背景:我希望在DTO映射到实体时挂钩业务规则.我认为将映射封装到扩展方法将是一个很好的途径.

IEntityDto是可以直接映射到实体的所有DTO实现的接口.

单个实例工作正常:

public static TEntity MapTo<TEntity>(this IEntityDto dto)
{
    ... Run Business Rules that don't require db access ...
    return AutoMapper.Mapper.Map<TEntity>(dto);
}
Run Code Online (Sandbox Code Playgroud)

我也想以同样的方式扩展ICollection:

public static ICollection<TEntity> MapToCollection<TEntity>(this ICollection<IEntityDto> dtos)
{
    ... Run Business Rules that don't require db access ...
    return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,MapToCollection没有显示在上下文菜单上,也不会在应用于IEntlection的ICollection时进行编译.

为了让这个工作,我错过了什么?我是否需要扩展ICollection,其中T是IEntityDto?在调用扩展方法时,我宁愿不必包含DTO类型.

public static ICollection<TEntity>MapToCollection<TDto,TEntity>(this ICollection<TDto> dtos) where TDto: IEntityDto
{
    ... Do Work and Return ...
}
Run Code Online (Sandbox Code Playgroud)

上面的工作,但我希望从集合推断T.

谢谢!

Jon*_*eet 5

实际上需要一个签名为的方法

public static ICollection<TEntity> MapToCollection<TEntity, TEntityDto>(
    this ICollection<TEntityDto> dtos)
    where TEntityDto : IEntityDto
Run Code Online (Sandbox Code Playgroud)

...但是这会强制你指定两个类型参数,我知道你不想这样做.

你可以做的是两次跳,例如

public static class DtoExtensions
{
    public static CollectionMapper<TEntityDto> Map(this ICollection<TEntityDto> dtos)
        where TEntityDto : IEntityDto
    {
        return new CollectionMapper<TEntityDto>(dtos);
    }
}

public class CollectionMapper<TEntityDto> where TEntityDto : IEntityDto
{
    private readonly ICollection<TEntityDto> dtos;

    public CollectionMapper(ICollection<TEntityDto> dtos)
    {
        this.dtos = dtos;
    }

    public ICollection<TEntity> To<TEntity>()
    {
        // Business rules...
        return AutoMapper.Mapper.Map<ICollection<TEntity>>(dtos);
    }
}
Run Code Online (Sandbox Code Playgroud)

您现在可以使用:

var result = collection.Map().To<FooEntity>();
Run Code Online (Sandbox Code Playgroud)

Map呼叫推断TEntityDto,而您指定TEntityTo电话.