【问题标题】:Refactoring two very similar overloads重构两个非常相似的重载
【发布时间】:2016-06-20 19:58:59
【问题描述】:

我有一个超载:

public DataTable ExecuteStoredProcedure(string storedProcedure)
        {
            var dataTable = new DataTable();
            using (var odbcConnection = _connection)
            {
                using (var odbcCommand = odbcConnection.CreateCommand())
                {
                    odbcCommand.CommandText = storedProcedure;
                    odbcCommand.CommandType = CommandType.StoredProcedure;
                    using (var adapter = new OdbcDataAdapter(odbcCommand))
                    {
                        adapter.Fill(dataTable);
                    }
                }
            }

            return dataTable;
        }

还有另一个重载:

    public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters)
    {
        var dataTable = new DataTable();
        using (var odbcConnection = _connection)
        {
            using (var odbcCommand = odbcConnection.CreateCommand())
            {
                odbcCommand.CommandText = storedProcedure;

                foreach (var parameter in storedProcedureParameters)
                {
                    odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, 
                        parameter.LengthOfParameter).Value = parameter.ParameterName;
                }

                odbcCommand.CommandType = CommandType.StoredProcedure;
                using (var adapter = new OdbcDataAdapter(odbcCommand))
                {
                    adapter.Fill(dataTable);
                }
            }
        }

        return dataTable;
    }

其内容非常相似。实际上如此相似,唯一的区别是这里的这一行:

foreach (var parameter in storedProcedureParameters)
                    {
                        odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, 
                            parameter.LengthOfParameter).Value = parameter.ParameterName;
                    }

我花了几个小时试图重构这个家伙,因为它们非常相似。我尝试过委托,但它使代码更难读。我无法组合这两个重载的功能,因为其他重载逻辑发生在另一个重载的中间。有人对如何将其重构为一种可读方法有任何想法吗?

【问题讨论】:

    标签: c# refactoring


    【解决方案1】:

    你可以做的几件事:

    您总是可以只使用一种方法,但可以使用可选的List&lt;StoredProcedureParameters&gt;

    像这样:(为简洁起见,我将其重命名为spParams

    public DataTable ExecuteStoredProcedure(string storedProcedure,
                                            List<StoredProcedureParameters> spParams
                                                         = new List<StoredProcedureParameters>())
    {
        var dataTable = new DataTable();
        using (var odbcConnection = _connection)
        {
            using (var odbcCommand = odbcConnection.CreateCommand())
            {
                odbcCommand.CommandText = storedProcedure;
    
                foreach (var parameter in spParams)
                {
                    odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, 
                        parameter.LengthOfParameter).Value = parameter.ParameterName;
                }
    
                odbcCommand.CommandType = CommandType.StoredProcedure;
                using (var adapter = new OdbcDataAdapter(odbcCommand))
                {
                    adapter.Fill(dataTable);
                }
            }
        }
    
        return dataTable;
    }
    

    这样,你可以调用相同的方法,并选择是否传入List&lt;StoredProcedureParameters&gt;(或不传入)。

    使用默认值为spParams= new List&lt;StoredProcedureParameters&gt;() 的参数意味着任何调用原始1 参数签名的现有代码仍然可以工作,从而节省额外重构的时间。

    另外,这意味着您现有的 foreach 块只会遍历一个空列表。

    你可以像上面那样做,只是将spParams的值设为null作为默认值,然后做一个空检查,像这样:

    public DataTable ExecuteStoredProcedure(string storedProcedure,
                                            List<StoredProcedureParameters> spParams = null)
    {
        //...
    
        if (spParams != null) // Check if the spParams is null
        {
            foreach(var param in spParams)
            {
                // Loop in here, if not null
            }
        }
    
        //...
    }
    

    希望这会有所帮助:)

    【讨论】:

      【解决方案2】:

      两种方法-

      1. 您可以让第一个方法将一个空的参数列表传递给第二个方法:

        public DataTable ExecuteStoredProcedure(string storedProcedure)
        {
            return ExecuteStoredProcedure(storedProcedure, new List<StoredProcedureParameters>());
        }
        
      2. 您可以从第一个方法传递 null 并在第二个方法中添加一个 null 检查,如下所示:

        public DataTable ExecuteStoredProcedure(string storedProcedure)
        {
            return ExecuteStoredProcedure(storedProcedure, null);
        }
        

        ...

        if (storedProcedureParameters != null)
        {
                foreach (var parameter in storedProcedureParameters)
                {
                        odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, parameter.LengthOfParameter).Value = parameter.ParameterName;
                }
        }
        

      【讨论】:

        【解决方案3】:

        您可以添加一个标志来标记是否要运行 foreach。当然有必要更改参数名称,这只是重构的一种可能变体:

        public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters, bool withForEach)
            {
                var dataTable = new DataTable();
                using (var odbcConnection = _connection)
                {
                    using (var odbcCommand = odbcConnection.CreateCommand())
                    {
                        odbcCommand.CommandText = storedProcedure;
                        if(withForEach)
                        foreach (var parameter in storedProcedureParameters)
                        {
                            odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, 
                                parameter.LengthOfParameter).Value = parameter.ParameterName;
                        }
        
                        odbcCommand.CommandType = CommandType.StoredProcedure;
                        using (var adapter = new OdbcDataAdapter(odbcCommand))
                        {
                            adapter.Fill(dataTable);
                        }
                    }
                }
        
                return dataTable;
            }
        

        【讨论】:

          【解决方案4】:

          为什么你不能做这样的事情......

          public DataTable ExecuteStoredProcedure(string storedProcedure)
          {
              return ExecuteStoredProcedure(storedProcedure, null);
          }
          
          public DataTable ExecuteStoredProcedure(string storedProcedure, List<StoredProcedureParameters> storedProcedureParameters)
          {
              var dataTable = new DataTable();
              using (var odbcConnection = _connection)
              {
                  using (var odbcCommand = odbcConnection.CreateCommand())
                  {
                      odbcCommand.CommandText = storedProcedure;
          
                      if(storedProcedureParameters != null)
                      {
                          foreach (var parameter in storedProcedureParameters)
                          {
                              odbcCommand.Parameters.Add("@" + parameter.ParameterName, parameter.ParameterType, 
                                  parameter.LengthOfParameter).Value = parameter.ParameterName;
                          }
                      }
          
                      odbcCommand.CommandType = CommandType.StoredProcedure;
                      using (var adapter = new OdbcDataAdapter(odbcCommand))
                      {
                          adapter.Fill(dataTable);
                      }
                  }
              }
          
              return dataTable;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-01-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多