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

编写C#泛型方法实现字典到对象实例列表的映射

解决方案

实现思路

核心是遍历Dictionary<long, string>的键值对,将键映射到目标类T的Id属性、值映射到Value属性。以下提供几种不同灵活度的实现方式,适配不同场景需求。

方法实现

方法1:反射驱动的通用实现

无需目标类定义特定构造函数,只要T拥有可写的long类型Id和string类型Value属性即可:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

public static class DictionaryExtensions
{
    public static IEnumerable<T> ToIdValueEnumerable<T>(this Dictionary<long, string> dictionary) where T : new()
    {
        if (dictionary == null)
            throw new ArgumentNullException(nameof(dictionary));

        var idProp = typeof(T).GetProperty(nameof(T.Id), BindingFlags.Public | BindingFlags.Instance);
        var valueProp = typeof(T).GetProperty(nameof(T.Value), BindingFlags.Public | BindingFlags.Instance);

        if (idProp == null || !idProp.CanWrite)
            throw new InvalidOperationException($"{typeof(T)}必须包含可写的long类型'Id'属性");
        if (valueProp == null || !valueProp.CanWrite)
            throw new InvalidOperationException($"{typeof(T)}必须包含可写的string类型'Value'属性");

        foreach (var kvp in dictionary)
        {
            var instance = new T();
            idProp.SetValue(instance, kvp.Key);
            valueProp.SetValue(instance, kvp.Value);
            yield return instance;
        }
    }
}

方法2:构造函数/委托驱动的高性能实现

如果目标类可以定义特定构造函数,或者允许自定义实例创建逻辑,这种方式性能更优:

public static class DictionaryExtensions
{
    // 重载1:依赖T的(long, string)构造函数
    public static IEnumerable<T> ToIdValueEnumerable<T>(this Dictionary<long, string> dictionary) where T : class
    {
        if (dictionary == null)
            throw new ArgumentNullException(nameof(dictionary));

        var constructor = typeof(T).GetConstructor(new[] { typeof(long), typeof(string) });
        if (constructor == null)
            throw new InvalidOperationException($"{typeof(T)}需要包含接收(long, string)参数的构造函数");

        foreach (var kvp in dictionary)
        {
            var instance = (T)constructor.Invoke(new object[] { kvp.Key, kvp.Value });
            yield return instance;
        }
    }

    // 重载2:自定义实例创建逻辑,灵活度最高
    public static IEnumerable<T> ToIdValueEnumerable<T>(this Dictionary<long, string> dictionary, Func<long, string, T> factory)
    {
        if (dictionary == null)
            throw new ArgumentNullException(nameof(dictionary));
        if (factory == null)
            throw new ArgumentNullException(nameof(factory));

        return dictionary.Select(kvp => factory(kvp.Key, kvp.Value));
    }
}

使用示例

假设有目标类:

public class MyData
{
    public long Id { get; set; }
    public string Value { get; set; }

    // 可选:用于方法2重载1的构造函数
    public MyData(long id, string value)
    {
        Id = id;
        Value = value;
    }
}

调用方式:

var dict = new Dictionary<long, string>
{
    { 1, "First" },
    { 2, "Second" }
};

// 方法1调用
var result1 = dict.ToIdValueEnumerable<MyData>();

// 方法2重载1调用(需对应构造函数)
var result2 = dict.ToIdValueEnumerable<MyData>();

// 方法2重载2调用(自定义实例逻辑)
var result3 = dict.ToIdValueEnumerable((id, val) => new MyData { Id = id, Value = val });

选择建议

  • 追求通用性(无需目标类修改):选方法1;
  • 追求性能且目标类可定义构造函数:选方法2重载1;
  • 需要自定义映射逻辑(比如属性名不一致、额外初始化):选方法2重载2。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:45:37