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

C#重构方法:减少Switch语句数量的方案咨询

重构C#搜索类以消除重复Switch语句

嘿,这个重复的switch问题确实很常见,你的代码里三次基于model.Attribute的分支判断完全可以被收拢,让代码更简洁、易维护。我推荐用策略模式来重构,把每个搜索类型的专属逻辑封装成独立的策略类,彻底干掉冗余的switch。

第一步:定义搜索策略接口

先创建一个接口,把每个搜索类型需要实现的三个核心逻辑(获取存储过程名、添加参数、映射结果)抽象出来:

public interface ISearchStrategy
{
    // 返回对应的存储过程名称
    string GetStoredProcedureName();
    
    // 根据SearchModel给SqlCommand添加参数
    void AddParameters(SqlCommand cmd, SearchModel model);
    
    // 把SqlDataReader的数据映射到ResultModel
    void MapResult(SqlDataReader reader, ResultModel result);
}

第二步:为每个搜索类型实现策略类

针对Users、Favorites、Email分别实现接口,每个类只负责自己的专属逻辑:

Users搜索策略

public class UsersSearchStrategy : ISearchStrategy
{
    public string GetStoredProcedureName() => "GeneralUserSearch";

    public void AddParameters(SqlCommand cmd, SearchModel model)
    {
        if (!string.IsNullOrWhiteSpace(model.Name))
            cmd.Parameters.AddWithValue("Name", model.Name);
        if (!string.IsNullOrWhiteSpace(model.Username))
            cmd.Parameters.AddWithValue("Username", model.Username);
    }

    public void MapResult(SqlDataReader reader, ResultModel result)
    {
        result.Users.Add(reader["User"]);
    }
}

Favorites搜索策略

public class FavoritesSearchStrategy : ISearchStrategy
{
    public string GetStoredProcedureName() => "UserFavorites";

    public void AddParameters(SqlCommand cmd, SearchModel model)
    {
        cmd.Parameters.AddWithValue("Favorites", model.Favorites);
    }

    public void MapResult(SqlDataReader reader, ResultModel result)
    {
        result.User = reader["User"];
        result.Favorites = reader["Favorites"];
    }
}

Email搜索策略

public class EmailSearchStrategy : ISearchStrategy
{
    public string GetStoredProcedureName() => "EmailSearch";

    public void AddParameters(SqlCommand cmd, SearchModel model)
    {
        cmd.Parameters.AddWithValue("Email", model.Email);
    }

    public void MapResult(SqlDataReader reader, ResultModel result)
    {
        result.User = reader["User"];
        result.Email = reader["Email"];
    }
}

第三步:重构主方法,用字典映射策略

现在把原来的主方法里的switch全部替换成字典查找,代码一下子就清爽了:

// 静态字典,提前注册所有搜索策略
private static readonly Dictionary<string, ISearchStrategy> _searchStrategies = new Dictionary<string, ISearchStrategy>
{
    { "Users", new UsersSearchStrategy() },
    { "Favorites", new FavoritesSearchStrategy() },
    { "Email", new EmailSearchStrategy() }
};

public static SearchModel GetSearchResults(SearchModel model)
{
    List<ResultModel> results = new List<ResultModel>();
    try
    {
        // 查找对应策略,处理无效的Attribute情况
        if (!_searchStrategies.TryGetValue(model.Attribute, out var strategy))
        {
            model.ErrorMessage = $"无效的搜索类型:{model.Attribute}";
            model.Results = results;
            return model;
        }

        using (SqlConnection conn = new SqlConnection("connection string"))
        {
            conn.Open();
            using (SqlCommand cmd = AdoBase.GetSqlCommand(strategy.GetStoredProcedureName(), conn))
            {
                // 调用策略添加参数
                strategy.AddParameters(cmd, model);

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            ResultModel result = new ResultModel();
                            // 调用策略映射结果
                            strategy.MapResult(reader, result);
                            results.Add(result);
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        // 注意:原代码返回Exception是错误的(方法返回类型是SearchModel),这里改成记录错误信息
        model.ErrorMessage = $"搜索失败:{ex.Message}";
    }

    // 把结果赋值给model(假设SearchModel有Results属性)
    model.Results = results;
    return model;
}

重构后的好处

  • 彻底消除重复switch:所有分支逻辑都被封装到各自的策略类里,主方法只负责通用流程
  • 符合开闭原则:以后新增搜索类型,只需要加新的策略类和字典项,不用修改主方法代码
  • 职责单一:每个策略类只处理一种搜索类型的逻辑,代码更易读、易测试
  • 可扩展性强:如果某个搜索类型需要调整逻辑,直接修改对应的策略类即可,不影响其他部分

另外提个小建议:原代码里的catch块直接返回ex是不符合方法返回类型的,我已经改成在model里设置错误信息,你可以根据实际需求调整错误处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:46:04