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

C#中如何实现类似TypeScript联合类型的多小对象合并为大对象功能

C# 合并多类型属性生成新类型的实现方案

以下是不同场景下的可行实现方案:

  • 方案1:源生成器(Source Generator,C# 9.0+ 推荐)
    该方案是最贴合需求的实现,可在编译期自动生成完整的强类型FullPerson代码,无需手动编写任何属性逻辑,生成的代码和手写类性能完全一致,支持编译时类型检查。
    你可以先自定义标记特性,只需给空分部类加特性标记即可:

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public class MergeFromAttribute : Attribute
    {
        public Type TargetType { get; }
        public MergeFromAttribute(Type targetType) => TargetType = targetType;
    }
    
    // 仅需定义空分部类加标记,剩余代码由源生成器自动生成
    [MergeFrom(typeof(Person))]
    [MergeFrom(typeof(PersonDetails))]
    [MergeFrom(typeof(PersonMeta))]
    public partial class FullPerson;
    

    源生成器逻辑为:扫描所有标记了MergeFrom的分部类,读取所有指定类型的公共属性,自动生成对应属性的实现代码。优点是强类型、无运行时开销、维护成本低,社区有大量现成的开源实现可直接复用,缺点需要C# 9.0及以上版本支持。

  • 方案2:T4 文本模板生成
    该方案是.NET生态中成熟的预生成代码方案,适合合并规则固定的场景。你可以在T4模板中通过反射读取待合并类型的结构,自动生成FullPerson的.cs代码文件。优点是不需要高版本C#支持,逻辑简单易调试,缺点是模板调整后需要手动触发重新生成,动态适配能力弱。

  • 方案3:组合包装类
    如果不想引入代码生成工具,可以用属性转发的方式减少逻辑重复:

    public class FullPerson
    {
        private readonly Person _person;
        private readonly PersonDetails _details;
        private readonly PersonMeta _meta;
    
        public FullPerson(Person person, PersonDetails details, PersonMeta meta)
        {
            _person = person;
            _details = details;
            _meta = meta;
        }
    
        public string FirstName 
        { 
            get => _person.FirstName; 
            set => _person.FirstName = value; 
        }
        public string LastName 
        { 
            get => _person.LastName; 
            set => _person.LastName = value; 
        }
        // 其余属性同理转发即可
    }
    

    优点是无需额外工具、逻辑完全可控,缺点是属性较多时手动编写转发代码的工作量较大。

  • 方案4:动态类型方案
    如果你不需要编译时类型校验,可以直接用ExpandoObject动态合并属性:

    public static dynamic MergeObjects(params object[] objects)
    {
        IDictionary<string, object> expando = new ExpandoObject();
        foreach (var obj in objects)
        {
            foreach (var prop in obj.GetType().GetProperties())
            {
                expando[prop.Name] = prop.GetValue(obj);
            }
        }
        return expando;
    }
    
    // 使用示例
    var fullPerson = MergeObjects(new Person(), new PersonDetails(), new PersonMeta());
    fullPerson.FirstName = "张三";
    fullPerson.Age = 20;
    

    优点是完全不需要定义额外类、灵活度极高,缺点是无智能提示、编译时不做属性校验、运行时出错概率高、性能弱于强类型。

  • 方案5:运行时动态生成类型
    如果你需要在运行时动态构造合并后的强类型,可以使用System.Reflection.Emit下的TypeBuilder动态生成类型结构。优点是完全运行时动态,无需提前定义类型,缺点是实现复杂度极高、调试难度大、性能低于编译时生成的类型,仅适合特殊的框架级场景使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:06:07