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

如何基于两个C#源类更优雅地创建符合属性映射要求的自定义对象

从两个C#类数据源生成组合自定义对象的实现方案

注意:你提供的类A构造函数中有拼写错误,LasetName = lastName 应为 LastName = lastName,否则初始化时会报错。

你当前的写法在属性量少的时候可以正常运行,但当属性数量较多时,映射逻辑会散落在业务代码各处,修改字段映射规则时需要逐一修改调用点,维护成本很高,这里提供几种可维护性更高的实现方案,适配不同的业务场景:

方案1:自定义类封装静态工厂方法(最推荐,无第三方依赖)

把所有映射逻辑集中封装在目标Custom类中,后续修改映射规则只要调整一处即可,还可以统一添加参数非空校验、属性冲突处理(例如A和B的LastName不一致时的取值逻辑)等通用逻辑。

public class Custom
{
    // 原有构造函数
    public Custom(string lastName, string firstName, string street, string city, int shoeSize)
    {
        LastName = lastName;
        FirstName = firstName;
        Street = street;
        City = city;
        ShoeSize = shoeSize;
    }

    // 新增静态工厂方法,统一处理A、B到Custom的映射
    public static Custom CreateFromAB(A sourceA, B sourceB)
    {
        // 可在这里添加参数非空校验、属性一致性校验等逻辑
        if (sourceA == null) throw new ArgumentNullException(nameof(sourceA));
        if (sourceB == null) throw new ArgumentNullException(nameof(sourceB));
        
        return new Custom(
            lastName: sourceA.LastName,
            firstName: sourceA.FirstName,
            street: sourceA.Street,
            city: sourceB.City,
            shoeSize: sourceB.ShoeSize
        );
    }

    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public int ShoeSize { get; set; }
}

业务侧调用代码非常简洁:

var a = new A("dd", "afafd", "asdf","adf");
var b = new B("dd", "afafd", "asdf","adf",22);
var custom = Custom.CreateFromAB(a, b);

方案2:扩展方法实现(适配无法修改Custom类定义的场景)

如果因为权限、依赖层级等原因不能修改Custom类的源码,可以通过扩展方法封装映射逻辑:

// 放在单独的映射扩展类中,避免污染源类定义
public static class MappingExtensions
{
    public static Custom ToCustom(this A sourceA, B sourceB)
    {
        if (sourceA == null) throw new ArgumentNullException(nameof(sourceA));
        if (sourceB == null) throw new ArgumentNullException(nameof(sourceB));
        
        return new Custom(
            sourceA.LastName, 
            sourceA.FirstName, 
            sourceA.Street, 
            sourceB.City, 
            sourceB.ShoeSize
        );
    }
}

业务侧调用方式:

var custom = a.ToCustom(b);

方案3:对象映射库实现(适配属性量极大、映射规则复杂的场景)

如果两个源类的属性数量非常多(几十上百个),手动写映射代码重复工作量大,可以使用AutoMapper这类成熟的对象映射库,通过配置约定减少重复代码,同名属性可以默认自动映射,不需要逐一配置。
映射配置示例:

// 全局只需要配置一次
var mapperConfig = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<(A a, B b), Custom>()
        // 非同名/非默认映射规则单独配置,同名属性自动映射
        .ForMember(dest => dest.City, opt => opt.MapFrom(src => src.b.City))
        .ForMember(dest => dest.ShoeSize, opt => opt.MapFrom(src => src.b.ShoeSize));
});
var mapper = mapperConfig.CreateMapper();

业务侧调用:

var custom = mapper.Map<Custom>((a, b));

内容的提问来源于stack exchange,提问作者Dario M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:09:00