You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Automapper中自定义的List<KeyValuePair>映射泛型化?

实现泛型的KeyValuePair映射方案

没问题!要把你当前的KeyValuePair自定义映射改成可复用的泛型实现,让它能适配任意类型的键值对转换,咱们可以利用AutoMapper的开放泛型映射配置来搞定,具体步骤如下:

1. 配置泛型KeyValuePair映射规则

首先在AutoMapper的初始化配置中,注册一个通用的KeyValuePair<TSourceKey, TSourceValue>到KeyValuePair<TDestKey, TDestValue>的映射规则,它会自动处理任意类型的键和值的转换(前提是你已经注册了对应基础类型的映射):

// 如果是旧版静态Mapper方式
Mapper.Initialize(cfg =>
{
    // 注册开放泛型的KeyValuePair映射
    cfg.CreateMap(typeof(KeyValuePair<,>), typeof(KeyValuePair<,>))
        .ConstructUsing((sourceObj, context) =>
        {
            // 获取源KeyValuePair的Key和Value
            var sourceType = sourceObj.GetType();
            var sourceKey = sourceType.GetProperty("Key").GetValue(sourceObj);
            var sourceValue = sourceType.GetProperty("Value").GetValue(sourceObj);

            // 获取目标类型的泛型参数(TDestKey和TDestValue)
            var destType = context.DestinationType;
            var destKeyType = destType.GetGenericArguments()[0];
            var destValueType = destType.GetGenericArguments()[1];

            // 分别映射Key和Value到目标类型
            var mappedKey = context.Mapper.Map(sourceKey, sourceType.GetGenericArguments()[0], destKeyType);
            var mappedValue = context.Mapper.Map(sourceValue, sourceType.GetGenericArguments()[1], destValueType);

            // 创建并返回目标KeyValuePair实例
            return Activator.CreateInstance(destType, mappedKey, mappedValue);
        });

    // 必须注册基础类型的映射(这一步不能忘!)
    cfg.CreateMap<MenuTable, Menu>();
    cfg.CreateMap<RoleTable, Role>();
});

// 如果是新版依赖注入的MapperConfiguration方式(更推荐)
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap(typeof(KeyValuePair<,>), typeof(KeyValuePair<,>))
        .ConstructUsing((sourceObj, context) =>
        {
            // 同上的映射逻辑
            var sourceType = sourceObj.GetType();
            var sourceKey = sourceType.GetProperty("Key").GetValue(sourceObj);
            var sourceValue = sourceType.GetProperty("Value").GetValue(sourceObj);

            var destType = context.DestinationType;
            var destKeyType = destType.GetGenericArguments()[0];
            var destValueType = destType.GetGenericArguments()[1];

            var mappedKey = context.Mapper.Map(sourceKey, sourceType.GetGenericArguments()[0], destKeyType);
            var mappedValue = context.Mapper.Map(sourceValue, sourceType.GetGenericArguments()[1], destValueType);

            return Activator.CreateInstance(destType, mappedKey, mappedValue);
        });

    cfg.CreateMap<MenuTable, Menu>();
    cfg.CreateMap<RoleTable, Role>();
});
var mapper = config.CreateMapper();

2. 调用泛型映射

配置完成后,你调用映射的方式和之前完全一样,AutoMapper会自动匹配泛型规则:

// 静态方式
var result = Mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(yourSourceList);

// 实例方式
var result = mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(yourSourceList);

3. 扩展复用性说明

这个泛型配置的好处在于一次配置,终身复用:

  • 如果你以后需要转换其他类型的KeyValuePair,比如KeyValuePair<UserTable, List<PermissionTable>>到KeyValuePair<User, List<Permission>>,只要注册UserTable→User和PermissionTable→Permission的基础映射,这个泛型规则就会自动生效,不用再写新的ConstructUsing。
  • 对于集合类型的Value(比如List<RoleTable>),AutoMapper默认已经支持集合到集合的转换,只要元素的映射存在,所以你不需要额外配置集合的映射规则。

内容的提问来源于stack exchange,提问作者SventoryMang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:53:55