【问题标题】:.NET code refactoring when overloads differ on data type重载在数据类型上不同时的 .NET 代码重构
【发布时间】:2009-11-23 12:15:07
【问题描述】:

我有一段代码,其中有 2 个重载,它们因参数的数据类型不同而不同,并且参数数量也不同。我希望减少代码重复。有哪些可能的方法可以做到这一点?

我的代码如下所示:

    public void publicMethod(double[,] data, double increment)
    {
        helperMethod1(data, increment);
    }

    public void publicMethod(double[,] data, TimeSpan increment, Enum someEnum)
    {
        helperMethod2(data, increment, someEnum);
    }

    //The helper methods are in a different class
    internal void helperMethod1(double[,] data, double increment)
    {
        //Some 20 lines of common code

        for (int i = 0; i < data.GetLength(0); ++i)
        {
            TargetFunction((double[])GetRow(i, data), increment);
        }

        //Some more common code
    }

    internal void helperMethod1(double[,] data, TimeSpan increment, Enum someEnum)
    {
        //Some 20 lines of common code

        for (int i = 0; i < data.GetLength(0); ++i)
        {
            TargetFunction((double[])GetRow(i, data), increment, someEnum);
        }

        //Some more common code
    }

    public static double[] GetRow(int rowIndex, double[,] array)
    {
        double[] row = new double[array.GetLength(1)];
        Buffer.BlockCopy(array, array.GetLength(1) * rowIndex * 8, row, 0, array.GetLength(1) * 8);
        return row;
    }

更新:

好的。看起来我没有很好地解释我的代码。我将粘贴我拥有的确切代码,以便你们获得更好的图片:

    public class PublicClass
    {
        public void PlotXAppendMultiple(double[,] xData, DataOrientation orientation, TimeSpan increment, PrecisionMode precisionMode)
        {
            HelperClass.PlotXAppendMultiple(xData, orientation, increment, precisionMode);
        }

        public void PlotXAppendMultiple(double[,] xData, DataOrientation orientation, double increment)
        {
            HelperClass.PlotXAppendMultiple(xData, orientation, increment);
        }
    }

    internal class HelperClass
    {
        public virtual void PlotXAppendMultiple(double[,] xData, DataOrientation orientation, double increment)
        {
            switch (orientation)
            {
                case (DataOrientation.DataInRows):
                    {
                        for (int i = 0; i < xData.GetLength(0); ++i)
                        {
                            TargetFunction((double[])GetRow(i, xData), increment);
                        }
                        break;
                    }
                case (DataOrientation.DataInColumns):
                    {
                        for (int i = 0; i < xData.GetLength(1); ++i)
                        {
                            TargetFunction((double[])GetColumn(i, xData), increment);
                        }
                        break;
                    }
                default:
                    {
                        break;
                    }
            }
        }

        public virtual void PlotXAppendMultiple(double[,] xData, DataOrientation orientation, TimeSpan increment, PrecisionMode precisionMode )
        {
            switch (orientation)
            {
                case (DataOrientation.DataInRows):
                    {
                        for (int i = 0; i < xData.GetLength(0); ++i)
                        {
                            TargetFunction((double[])GetRow(i, xData), increment, precisionMode);
                        }
                        break;
                    }
                case (DataOrientation.DataInColumns):
                    {
                        for (int i = 0; i < xData.GetLength(1); ++i)
                        {
                            TargetFunction((double[])GetColumn(i, xData), increment, precisionMode);
                        }
                        break;
                    }
                default:
                    {
                        break;
                    }
            }
        }
    }

我不想修改我正在使用的枚举(所以基本上我想向它添加虚拟条目)。甚至有可能/值得重构这段代码吗?

【问题讨论】:

    标签: c# .net refactoring overloading


    【解决方案1】:

    在这两种方法中用TwentyLinesOfCommonCode()//Some more common code 替换//Some 20 lines of common code 怎么样?您将只保留非通用代码。

    【讨论】:

    • 是的。有时您只需要查看要重构的什么
    • 是的,如果通用代码很简单,这本来可以做到的。但就我而言,常见代码包含大量 If-Else 和 switch 案例,因此无法将其移至其他方法。
    • 所以只是“有点常见”?
    【解决方案2】:

    在您的枚举中有一个条目“NotSet”或“Unknow”。 TargetFunction2 必须意识到它并适应它的行为。只保留带有 3 args 签名的 helperMethod1 并像这样调整第一个方法

    public void publicMethod(double[,] data, double increment)
        {
            helperMethod1(data, increment, Enum.Unknow);
        }
    

    【讨论】:

      【解决方案3】:

      是否可以创建一个转换器,将TimeSpanEnum 转换为Double 参数,反之亦然?

      如果是,那么你可以先定义这样一个辅助方法

      public double Convertor(TimeSpan ts, Enum enum)
      {
      }
      

      然后编写如下代码:

        //The helper methods are in a different class
          internal void helperMethod1(double[,] data, double increment)
          {
              //Some 20 lines of common code
      
              for (int i = 0; i < data.GetLength(0); ++i)
              {
                  TargetFunction1(data, increment);
              }
      
              //Some more common code
          }
      
          internal void helperMethod1(double[,] data, TimeSpan increment, Enum someEnum)
          {
              helperMethod1(data, Convertor(increment, someEnum);
          }
      

      【讨论】:

        【解决方案4】:

        我会从十进制参数创建一个TimeSpan 对象,并为这个新的TimeSpan 对象提供一个“默认”枚举值给采用3 个参数的方法。

        【讨论】:

          猜你喜欢
          • 2014-01-07
          • 2013-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多