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

如何通过继承从两个MVC Model中选取部分字段创建新类

问题解答

首先明确:C#不支持类的多继承,所以无法让OpeningBalanceDrCrMurg同时直接继承OpeningBalanceLiteModel和DrCrDetailLiteModel两个类,自然也没法仅通过继承从两个类各选3个字段而不手动声明。

不过可以通过以下几种替代方案实现你的需求:

方案1:组合(推荐)

采用面向对象的「组合优于继承」原则,在新类中嵌入两个原类的实例,暴露你需要的3+3个字段:

public class OpeningBalanceDrCrMurg
{
    private readonly OpeningBalanceLiteModel _openingBalance;
    private readonly DrCrDetailLiteModel _drCrDetail;

    public OpeningBalanceDrCrMurg(OpeningBalanceLiteModel openingBalance, DrCrDetailLiteModel drCrDetail)
    {
        _openingBalance = openingBalance;
        _drCrDetail = drCrDetail;
    }

    // 从OpeningBalanceLiteModel选取的3个字段
    public long LedgerId => _openingBalance.LedgerId;
    public string LedgerCode => _openingBalance.LedgerCode;
    public decimal OpeningBalance => _openingBalance.OpeningBalance;

    // 从DrCrDetailLiteModel选取的3个字段
    public int TransactionTypeId => _drCrDetail.TransactionTypeId;
    public decimal? Amount => _drCrDetail.Amount;
    public string VoucherNarration => _drCrDetail.VoucherNarration;
}

方案2:手动声明投影类(DTO)

如果不需要和原类实例保持关联,直接声明需要的6个字段,再通过映射工具(如AutoMapper)从原类赋值:

public class OpeningBalanceDrCrMurg
{
    public long LedgerId { get; set; }
    public string LedgerCode { get; set; }
    public decimal OpeningBalance { get; set; }

    public int TransactionTypeId { get; set; }
    public decimal? Amount { get; set; }
    public string VoucherNarration { get; set; }
}

// 使用AutoMapper赋值示例
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<OpeningBalanceLiteModel, OpeningBalanceDrCrMurg>();
    cfg.CreateMap<DrCrDetailLiteModel, OpeningBalanceDrCrMurg>();
});

var mapper = config.CreateMapper();
var mergedModel = new OpeningBalanceDrCrMurg();
mapper.Map(openingBalanceModel, mergedModel);
mapper.Map(drCrDetailModel, mergedModel);

方案3:接口契约+组合

先为需要的字段定义接口契约,让原类实现接口,再让新类通过组合实现接口:

// 定义OpeningBalance核心字段接口
public interface IOpeningBalanceCore
{
    long LedgerId { get; set; }
    string LedgerCode { get; set; }
    decimal OpeningBalance { get; set; }
}

// 定义DrCrDetail核心字段接口
public interface IDrCrDetailCore
{
    int TransactionTypeId { get; set; }
    decimal? Amount { get; set; }
    string VoucherNarration { get; set; }
}

// 原类实现对应接口(无需修改原有字段)
public class OpeningBalanceLiteModel : IOpeningBalanceCore { /* 原有字段保持不变 */ }
public class DrCrDetailLiteModel : IDrCrDetailCore { /* 原有字段保持不变 */ }

// 新类实现双接口,通过组合完成属性代理
public class OpeningBalanceDrCrMurg : IOpeningBalanceCore, IDrCrDetailCore
{
    private readonly IOpeningBalanceCore _openingBalance;
    private readonly IDrCrDetailCore _drCrDetail;

    public OpeningBalanceDrCrMurg(IOpeningBalanceCore openingBalance, IDrCrDetailCore drCrDetail)
    {
        _openingBalance = openingBalance;
        _drCrDetail = drCrDetail;
    }

    public long LedgerId { get => _openingBalance.LedgerId; set => _openingBalance.LedgerId = value; }
    public string LedgerCode { get => _openingBalance.LedgerCode; set => _openingBalance.LedgerCode = value; }
    public decimal OpeningBalance { get => _openingBalance.OpeningBalance; set => _openingBalance.OpeningBalance = value; }

    public int TransactionTypeId { get => _drCrDetail.TransactionTypeId; set => _drCrDetail.TransactionTypeId = value; }
    public decimal? Amount { get => _drCrDetail.Amount; set => _drCrDetail.Amount = value; }
    public string VoucherNarration { get => _drCrDetail.VoucherNarration; set => _drCrDetail.VoucherNarration = value; }
}

方案4:C# 9+ 记录类型解构合并

如果使用C# 9及以上版本,可利用记录的解构功能快速合并字段:

// 为原类添加解构方法
public class OpeningBalanceLiteModel
{
    // 原有字段...
    public void Deconstruct(out long ledgerId, out string ledgerCode, out decimal openingBalance)
    {
        ledgerId = LedgerId;
        ledgerCode = LedgerCode;
        openingBalance = OpeningBalance;
    }
}

public class DrCrDetailLiteModel
{
    // 原有字段...
    public void Deconstruct(out int transactionTypeId, out decimal? amount, out string voucherNarration)
    {
        transactionTypeId = TransactionTypeId;
        amount = Amount;
        voucherNarration = VoucherNarration;
    }
}

// 定义合并后的记录类
public record OpeningBalanceDrCrMurg(
    long LedgerId, 
    string LedgerCode, 
    decimal OpeningBalance, 
    int TransactionTypeId, 
    decimal? Amount, 
    string VoucherNarration);

// 使用示例
var (ledgerId, ledgerCode, openingBalance) = openingBalanceModel;
var (transactionTypeId, amount, voucherNarration) = drCrDetailModel;
var mergedModel = new OpeningBalanceDrCrMurg(ledgerId, ledgerCode, openingBalance, transactionTypeId, amount, voucherNarration);

内容的提问来源于stack exchange,提问作者Manish Singh Bisht

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:55:24