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

C#中实现类似JS扩展运算符的对象属性复制方案咨询

在C#中实现类似JS扩展运算符的对象属性复制方案

嘿,这个需求太有共鸣了!JS里的...扩展运算符确实能省不少事,C#里虽然没有原生支持,但除了你提到的逐个复制和反射+ExpandoObject,还有几个实用的思路可以试试:

  • 使用AutoMapper等映射库(适合中大型项目)
    这类库可以帮你自动处理属性映射,还能灵活添加额外字段。先配置好源对象和目标匿名类型的映射,之后就能一键复制属性并附加新字段:

    // 第一步:配置AutoMapper(建议放在项目启动逻辑里)
    var mapperConfig = new MapperConfiguration(cfg => 
    {
        cfg.CreateMap<YourSourceItem, dynamic>()
           .ForMember(dest => dest.Extra, opt => opt.MapFrom(_ => "additional property"));
    });
    var mapper = mapperConfig.CreateMapper();
    
    // 第二步:在LINQ中使用
    var result = items.Select(item => mapper.Map<dynamic>(item));
    

    如果你想更明确地控制匿名类型的结构,也可以先定义一个匿名模板,让AutoMapper直接映射到该类型:

    var anonTemplate = new { Prop1 = "", Prop2 = 0, Extra = "" };
    var result = items.Select(item => mapper.Map(anonTemplate, item));
    
  • 利用解构语法简化属性提取(C# 7.0+支持)
    给你的源对象添加解构方法,就能一次性取出所有属性,不用逐个写:

    // 给源类添加解构方法
    public class YourSourceItem
    {
        public string Prop1 { get; set; }
        public int Prop2 { get; set; }
    
        public void Deconstruct(out string prop1, out int prop2)
        {
            prop1 = Prop1;
            prop2 = Prop2;
        }
    }
    
    // 使用解构创建匿名对象
    var result = items.Select(item => 
    {
        var (prop1, prop2) = item;
        return new { prop1, prop2, Extra = "additional property" };
    });
    

    这种方式比手动逐个写属性清爽很多,而且类型安全。

  • 用记录类型(Record)搭配解构/With表达式(C# 9.0+支持)
    如果你的源对象是记录类型,解构会更方便;要是可以接受返回记录而非匿名对象,还能直接定义带额外字段的记录:

    // 源记录类型
    public record SourceItem(string Prop1, int Prop2);
    // 带额外字段的目标记录
    public record SourceItemWithExtra(string Prop1, int Prop2, string Extra);
    
    // 使用解构快速转换
    var result = items.Select(item => 
    {
        var (p1, p2) = item;
        return new SourceItemWithExtra(p1, p2, "additional property");
    });
    

    记录类型的不可变性和简洁语法,在需要复用带额外属性的对象时非常实用。

  • 自定义扩展方法实现轻量级属性复制
    自己写个简单的扩展方法,自动把源对象的属性复制到匿名对象模板里,不用手动写所有属性:

    public static class ObjectExtensions
    {
        public static T CopyPropsToAnonymous<T>(this object source, T targetTemplate)
        {
            var sourceProps = source.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
            var targetProps = targetTemplate.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
    
            foreach (var sourceProp in sourceProps)
            {
                var targetProp = targetProps.FirstOrDefault(p => p.Name == sourceProp.Name && p.PropertyType == sourceProp.PropertyType);
                if (targetProp != null && targetProp.CanWrite)
                {
                    targetProp.SetValue(targetTemplate, sourceProp.GetValue(source));
                }
            }
            return targetTemplate;
        }
    }
    
    // 使用时只需要定义包含所有需要属性的匿名模板
    var result = items.Select(item => item.CopyPropsToAnonymous(new 
    {
        item.Prop1, // 列出属性让编译器推断类型,扩展方法自动赋值
        item.Prop2,
        Extra = "additional property"
    }));
    

    这个方法兼顾了类型安全和便捷性,不用依赖第三方库。

以上几种方案各有适用场景:映射库适合复杂项目的全局映射,解构和记录类型适合现代C#版本的轻量场景,自定义扩展方法则是灵活的轻量级解决方案~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:37:55