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

C#代码重构:消除连续if语句提升可读性与可维护性

是否适合使用守卫子句优化

完全适合。你当前代码的核心可读性问题就是多层嵌套的连续if把核心业务逻辑包裹得太深,阅读者需要记住每层判断的条件才能理解后续逻辑,用反向判断提前退出的守卫子句是这类场景的标准优化方案,不会改变原有业务逻辑,还能大幅降低理解成本。

除了嵌套if的问题,你这段代码还有两个明显的维护隐患:一是处理CommerceMedia集合和Rockstar自定义文档的逻辑几乎1:1重复,后续修改规则很容易漏改其中一处;二是字典更新的分支里存在大量重复代码,还有冗余的引用类型重新赋值操作。

具体优化方向
  • 所有不满足执行条件的分支直接return/continue/break,把核心逻辑从嵌套块里解放出来,比如没有子节点直接返回空字典、无效媒体链接直接跳过当前循环、收到停止信号直接中断遍历。
  • 抽离重复的媒体关联处理逻辑为独立私有方法,不管媒体来源是系统CommerceMedia还是自定义产品文档,只要拿到了资源链接,就走同一套关联更新逻辑,消除重复代码。
  • 简化字典操作逻辑:不需要在TryGetValue的存在/不存在两个分支里重复写添加产品、添加分类的逻辑,判断key不存在时先初始化实例存入字典,后续统一更新实例属性即可——因为是引用类型,直接修改属性就会同步到字典里存储的对象,不需要再重复给字典key赋值。
  • 清理冗余代码:比如已经通过is做了类型转换判断后不需要再对转换后的对象做null检查;Guid是值类型不存在null的情况,不需要额外加null判断;空集合用Enumerable.Empty<T>()比new空List更高效。
优化后完整代码
private Dictionary<Guid, CommerceMediaFileAssociation<T>> GetMediaToContentsAssociations<T>(ref bool stopSignaled, CatalogContentBase catalog, CultureInfo culture, Action<string> onStatusChanged = null)
    where T : MediaData
{
    IEnumerable<ContentReference> descendentReferences = _contentLoader.GetDescendents(catalog.ContentLink);
    var associations = new Dictionary<Guid, CommerceMediaFileAssociation<T>>();

    // 守卫子句:无子节点直接返回
    if (!descendentReferences.Any()) return associations;

    var descendentProducts = _contentLoader.GetItems<BaseProduct>(descendentReferences, culture);
    foreach (var product in descendentProducts)
    {
        // 守卫子句:收到停止信号直接中断
        if (stopSignaled)
        {
            onStatusChanged?.Invoke($"Reindexing canceled.");
            break;
        }

        // 处理系统CommerceMedia资源
        if (product is IAssetContainer assetContainer && assetContainer.CommerceMediaCollection?.Any() == true)
        {
            foreach (CommerceMedia media in assetContainer.CommerceMediaCollection)
            {
                PermanentLinkMap mediaLinkMap = _permanentLinkMapper.Find(media.AssetLink);
                UpdateMediaAssociation(associations, mediaLinkMap, product);
            }
        }

        // 处理Rockstar自定义文档资源
        if (product is RockstarProduct rockstar)
        {
            var files = rockstar.Rockstar_Product_Product_Documents.FilteredItems.Select(x => x.GetContent() as IContentMedia) ?? Enumerable.Empty<IContentMedia>();
            foreach (var file in files)
            {
                PermanentLinkMap mediaLinkMap = _permanentLinkMapper.Find(file.ContentLink);
                UpdateMediaAssociation(associations, mediaLinkMap, product);
            }
        }
    }

    return associations;
}

/// <summary>
/// 抽离的通用媒体关联更新逻辑
/// </summary>
private void UpdateMediaAssociation<T>(Dictionary<Guid, CommerceMediaFileAssociation<T>> associations, PermanentLinkMap mediaLinkMap, BaseProduct product)
    where T : MediaData
{
    // 守卫子句:无效媒体链接直接跳过
    if (mediaLinkMap == null || mediaLinkMap.Guid == Guid.Empty) return;

    var productInfo = ProductUtilities.GetProductCategoriesAndPriority(product);
    var mediaKey = mediaLinkMap.Guid;

    // 不存在关联则先初始化,后续统一处理逻辑,消除分支重复
    if (!associations.TryGetValue(mediaKey, out var association))
    {
        association = new CommerceMediaFileAssociation<T>();
        associations.Add(mediaKey, association);
    }

    // 统一更新关联信息,无需在两个分支重复编写
    association.Products.Add($"{product.ContentGuid}||{product.MetaTitle}");
    if (productInfo.Categories?.Any() == true)
    {
        // 如果需要避免分类重复添加可以用UnionWith,不需要的话换回原来的foreach循环Add即可
        association.ProductCategories.UnionWith(productInfo.Categories);
    }
    association.Priority = productInfo.Priority;
}

优化后代码主逻辑缩进最多2层,流程一目了然,后续如果要新增第三种媒体来源,只需要拿到资源链接调用通用的UpdateMediaAssociation方法即可,不需要再复制大段重复逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:30:57