.NET code refactoring when overloads differ on data type
I have a piece of code where in there are 2 overloads which differ by data types of parameter and have different number of parameters as well. I am looking to reduce the code duplication. What are the possible ways I can do this?
My code looks like this:
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;
}
UPDATE:
OK. It looks like I am not explaining my code well enough. I will paste the exact code I have so that you guys get a better picture:
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 incremen开发者_StackOverflow中文版t)
{
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;
}
}
}
}
I dont want to modify the enums I am using (so basically I want to add dummy entries to it). Is it even possible/worth refactoring this code?
How about replacing //Some 20 lines of common code
with call to TwentyLinesOfCommonCode()
and //Some more common code
with SomeMoreCommonCode()
in both Methods? You would keep only the non-common code.
Have an entry "NotSet" or "Unknow" in your Enum. TargetFunction2 must be aware of it and adapt it's behavior. Keep only the helperMethod1 with the 3 args signature and adapt first method like this
public void publicMethod(double[,] data, double increment)
{
helperMethod1(data, increment, Enum.Unknow);
}
Is it possible to create a convertor that converts TimeSpan
and Enum
into the Double
parameter, or vice versa?
If yes, then you can define such a helper method first
public double Convertor(TimeSpan ts, Enum enum)
{
}
and then write the following code:
//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);
}
I'd create a TimeSpan
object from the decimal parameter and provide this new TimeSpan
object with a 'default' Enum value on to the method taking 3 parameters.
精彩评论