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

.NET如何从已有类型创建匿名类型并修改指定字段?

动态转换对象类型生成结构一致的简化对象(无需维护目标类)

你可以通过反射+递归类型转换的方式实现需求,无需手动维护简化类,只需要预设类型转换规则,就能自动生成和原对象结构一致的简化动态对象(用ExpandoObject模拟匿名类型的用法)。

核心实现思路

  1. 用反射遍历原对象的所有公开属性;
  2. 针对不同类型(布尔、枚举、列表、复杂对象)应用预设转换规则;
  3. 递归处理嵌套对象和列表元素;
  4. 用ExpandoObject存储转换后的属性和值,它可以像匿名类型一样直接访问属性。

完整代码示例

定义原类型和枚举

public enum MyEnum
{
    Value1 = 1,
    Value2 = 2
}

public class MyClass
{
    public string Str1 { get; set; }
    public bool B1 { get; set; }
    public MyEnum EnumVal { get; set; }
    // 扩展属性无需额外修改转换逻辑
    public List<MyClass> ChildItems { get; set; }
}

转换工具类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Reflection;

public static class SimplifiedObjectConverter
{
    // 可扩展的类型转换规则字典
    private static readonly Dictionary<Type, Func<object, object>> _typeConverters = new()
    {
        { typeof(bool), val => (bool)val ? 1 : 0 },
        { typeof(Enum), val => Convert.ToInt32(val) }
    };

    public static dynamic Convert(object source)
    {
        if (source == null) return null;

        var target = new ExpandoObject() as IDictionary<string, object>;
        var properties = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (var prop in properties)
        {
            var value = prop.GetValue(source);
            target[prop.Name] = ConvertValue(value);
        }

        return target;
    }

    private static object ConvertValue(object value)
    {
        if (value == null) return null;
        var valueType = value.GetType();

        // 优先使用预设的转换规则
        if (_typeConverters.TryGetValue(valueType, out var converter))
        {
            return converter(value);
        }
        // 处理枚举(兜底匹配所有枚举类型)
        if (valueType.IsEnum)
        {
            return Convert.ToInt32(value);
        }
        // 处理列表/集合(排除字符串)
        if (typeof(IEnumerable).IsAssignableFrom(valueType) && valueType != typeof(string))
        {
            var convertedList = new List<object>();
            foreach (var item in (IEnumerable)value)
            {
                convertedList.Add(ConvertValue(item));
            }
            return convertedList;
        }
        // 处理嵌套复杂对象
        if (valueType.IsClass && valueType != typeof(string))
        {
            return Convert(value);
        }
        // 其他类型直接返回原值
        return value;
    }
}

使用示例

// 构造原对象实例
var originalObj = new MyClass
{
    Str1 = "Some rand",
    B1 = true,
    EnumVal = MyEnum.Value1,
    ChildItems = new List<MyClass>
    {
        new() { Str1 = "Child 1", B1 = false, EnumVal = MyEnum.Value2 },
        new() { Str1 = "Child 2", B1 = true, EnumVal = MyEnum.Value1 }
    }
};

// 转换为简化对象
var simplifiedObj = SimplifiedObjectConverter.Convert(originalObj);

// 访问属性和匿名类型用法一致
Console.WriteLine(simplifiedObj.Str1); // 输出: Some rand
Console.WriteLine(simplifiedObj.B1); // 输出: 1
Console.WriteLine(simplifiedObj.EnumVal); // 输出: 1
Console.WriteLine(simplifiedObj.ChildItems[0].B1); // 输出: 0

方案优势

  • 无需维护目标类:原类新增/修改属性时,转换逻辑自动适配,不用手动同步简化类;
  • 规则可扩展:新增类型转换需求时,只需要在_typeConverters字典中添加对应的转换委托即可;
  • 支持嵌套结构:自动递归处理嵌套对象和列表,保持原对象的层级结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:52:39