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

合并两个合同标识符获取方法的技术求助

合并方法解决方案

我需要把以下两个方法合并成一个,但不知道该怎么做。我试过用IF语句判断employeeMark是否为空来区分执行不同逻辑,但只是把重复代码硬凑到了一个方法里。以下是两个方法的代码:

原方法代码

按合同码获取合同标识

private async Task<ProcessedContractsIdentifiers> GetContractsIdentifiersByContractsCodes(List<ImportableContractIdentifier> importableContractsIdentifiers)
{
    var errors = new List<ContractImportValidationErrorDto>();

    foreach (var contract in importableContractsIdentifiers.Where(contract => string.IsNullOrWhiteSpace(contract.ContractCode)))
    {
        errors.Add(new ContractImportValidationErrorDto
        {
            ValidatedCode = string.Empty,
            Line = contract.RowNumber,
            ErrorCode = ContractImportValidationErrorCode.ContractCodeIsRequired
        });
    }
    var contractsCodes = importableContractsIdentifiers.ConvertAll(x => x.ContractCode);
    contractsCodes = contractsCodes.Where(x => !string.IsNullOrWhiteSpace(x)).ToList();

    var contractsSignatures = await GetContractsSignaturesByContractsCodes(contractsCodes);
    var unresolvedContracts = contractsCodes.Except(contractsSignatures.Select(cs => cs.Code)).ToHashSet();
    foreach (var c in unresolvedContracts)
    {
        errors.Add(new ContractImportValidationErrorDto
        {
            ValidatedCode = c,
            ErrorCode = ContractImportValidationErrorCode.InvalidContractCode
        });
    }

    return new ProcessedContractsIdentifiers
    {
        IdentificationMethod = ContractIdentificationMethod.ByContractCode,
        IdentifiedContractsSignatures = contractsSignatures,
        NonIdentifiableContracts = errors
    };
}

按员工标识获取合同标识

private async Task<ProcessedContractsIdentifiers> GetContractsIdentifiersByEmployeesMarks(List<ImportableContractIdentifier> importableContractsIdentifiers)
{
    const int withSingleContract = 1;
    var errors = new List<ContractImportValidationErrorDto>();

    foreach (var contract in importableContractsIdentifiers.Where(contract => string.IsNullOrWhiteSpace(contract.EmployeeMark)))
    {
        errors.Add(new ContractImportValidationErrorDto
        {
            ValidatedCode = string.Empty,
            Line = contract.RowNumber,
            ErrorCode = ContractImportValidationErrorCode.EmployeeMarkIsRequired
        });
    }
    var employeesMarks = importableContractsIdentifiers.Select(x => x.EmployeeMark).Where(x => !string.IsNullOrWhiteSpace(x)).ToHashSet();

    var contractsSignatures = await GetContractsSignaturesByEmployeeMark(employeesMarks);
    var contractsGroupedByEmployeeMark = contractsSignatures.GroupBy(x => x.EmployeeMark);

    foreach (var contracts in contractsGroupedByEmployeeMark.Where(x => x.ToList().Count != withSingleContract))
    {
        errors.Add(new ContractImportValidationErrorDto
        {
            ValidatedCode = contracts.Key,
            ErrorCode = ContractImportValidationErrorCode.EmployeeMarkWithMultipleContracts
        });
    }

    var unresolvedMarks = employeesMarks.Except(contractsSignatures.Select(cs => cs.EmployeeMark)).ToHashSet();
    foreach (var eMark in unresolvedMarks)
    {
        errors.Add(new ContractImportValidationErrorDto
        {
            ValidatedCode = eMark,
            ErrorCode = ContractImportValidationErrorCode.InvalidEmployeeMark
        });
    }

    return new ProcessedContractsIdentifiers
    {
        IdentificationMethod = ContractIdentificationMethod.ByEmployeeMark,
        IdentifiedContractsSignatures = contractsSignatures,
        NonIdentifiableContracts = errors
    };
}

合并方案:提取公共逻辑,参数化差异点

两个方法核心流程一致,差异集中在字段选择、API调用、错误类型、额外检查逻辑,通过枚举参数+委托封装差异,避免重复代码。

合并后的完整代码

// 定义枚举标识处理类型(如果项目中已存在可忽略)
public enum ContractIdentificationType
{
    ByContractCode,
    ByEmployeeMark
}

private async Task<ProcessedContractsIdentifiers> GetContractsIdentifiers(List<ImportableContractIdentifier> importableContractsIdentifiers, ContractIdentificationType identificationType)
{
    var errors = new List<ContractImportValidationErrorDto>();
    const int withSingleContract = 1;

    // 封装差异点:字段提取、错误码、API调用、返回标识类型
    Func<ImportableContractIdentifier, string> getIdentifier;
    ContractImportValidationErrorCode requiredErrorCode;
    ContractImportValidationErrorCode invalidIdentifierErrorCode;
    Func<IEnumerable<string>, Task<IEnumerable<ContractSignature>>> getSignaturesAsync;
    ContractIdentificationMethod identificationMethod;

    switch (identificationType)
    {
        case ContractIdentificationType.ByContractCode:
            getIdentifier = contract => contract.ContractCode;
            requiredErrorCode = ContractImportValidationErrorCode.ContractCodeIsRequired;
            invalidIdentifierErrorCode = ContractImportValidationErrorCode.InvalidContractCode;
            getSignaturesAsync = codes => GetContractsSignaturesByContractsCodes(codes.ToList());
            identificationMethod = ContractIdentificationMethod.ByContractCode;
            break;
        case ContractIdentificationType.ByEmployeeMark:
            getIdentifier = contract => contract.EmployeeMark;
            requiredErrorCode = ContractImportValidationErrorCode.EmployeeMarkIsRequired;
            invalidIdentifierErrorCode = ContractImportValidationErrorCode.InvalidEmployeeMark;
            getSignaturesAsync = marks => GetContractsSignaturesByEmployeeMark(marks.ToHashSet());
            identificationMethod = ContractIdentificationMethod.ByEmployeeMark;
            break;
        default:
            throw new ArgumentOutOfRangeException(nameof(identificationType), identificationType, null);
    }

    // 公共逻辑:验证必填字段
    foreach (var contract in importableContractsIdentifiers.Where(c => string.IsNullOrWhiteSpace(getIdentifier(c))))
    {
        errors.Add(new ContractImportValidationErrorDto
        {
            ValidatedCode = string.Empty,
            Line = contract.RowNumber,
            ErrorCode = requiredErrorCode
        });
    }

    // 公共逻辑:提取有效标识(去重避免重复调用API)
    var validIdentifiers = importableContractsIdentifiers
        .Select(getIdentifier)
        .Where(id => !string.IsNullOrWhiteSpace(id))
        .Distinct()
        .ToList();

    // 公共逻辑:调用API获取合同签名
    var contractsSignatures = await getSignaturesAsync(validIdentifiers);

    // 差异逻辑:员工标识需检查多合同绑定情况
    if (identificationType == ContractIdentificationType.ByEmployeeMark)
    {
        var contractsGroupedByMark = contractsSignatures.GroupBy(s => s.EmployeeMark);
        foreach (var group in contractsGroupedByMark.Where(g => g.Count() != withSingleContract))
        {
            errors.Add(new ContractImportValidationErrorDto
            {
                ValidatedCode = group.Key,
                ErrorCode = ContractImportValidationErrorCode.EmployeeMarkWithMultipleContracts
            });
        }
    }

    // 公共逻辑:处理未找到的标识
    var resolvedIdentifiers = contractsSignatures.Select(s => 
        identificationType == ContractIdentificationType.ByContractCode ? s.Code : s.EmployeeMark);
    var unresolvedIdentifiers = validIdentifiers.Except(resolvedIdentifiers).ToHashSet();

    foreach (var id in unresolvedIdentifiers)
    {
        errors.Add(new ContractImportValidationErrorDto
        {
            ValidatedCode = id,
            ErrorCode = invalidIdentifierErrorCode
        });
    }

    // 公共逻辑:返回结果
    return new ProcessedContractsIdentifiers
    {
        IdentificationMethod = identificationMethod,
        IdentifiedContractsSignatures = contractsSignatures.ToList(),
        NonIdentifiableContracts = errors
    };
}

使用方式

替换原方法调用:

// 按合同码处理
var codeResult = await GetContractsIdentifiers(importableContracts, ContractIdentificationType.ByContractCode);

// 按员工标识处理
var markResult = await GetContractsIdentifiers(importableContracts, ContractIdentificationType.ByEmployeeMark);

优势

  • 公共逻辑仅维护一次,降低后续修改成本
  • 扩展性强:新增标识类型只需在switch中添加case
  • 逻辑分层清晰,差异点集中管理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:48:25