如何通过继承从两个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
相关产品推荐
相关产品推荐

