我如何重构这两种方法?

时间:2012-09-27 10:06:40

标签: c# refactoring

    public static void outputDetail(DateTime previousTime, ref double[] array, StreamWriter streamWriter)  //the parameter in here is not necessary, but want to maintain a similiarity in the TimeOfDay class
    {
        string outputString = previousTime.ToString("yyyy/MM/dd");
        Boolean bypass = true;

        for (int i = 1; i < array.Length - 1; i++)
        {
            outputString = outputString + "," + array[i].ToString();

            if (array[i] != 0)
                bypass = false;
        }
        if (bypass == false)
            streamWriter.WriteLine(outputString);

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = 0;
        }
    }


    public static void outputDetail(DateTime previousTime, ref int[] array, StreamWriter streamWriter)  //the parameter in here is not necessary, but want to maintain a similiarity in the TimeOfDay class
    {
        string outputString = previousTime.ToString("yyyy/MM/dd");
        Boolean bypass = true;

        for (int i = 1; i < array.Length -1; i++)
        {
            if (array[i] != 0)
            {
                outputString = outputString + "," + array[i].ToString();
                bypass = false;
            }
            else
            {
                outputString = outputString + ",";
            }
        }
        if (bypass == false)
            streamWriter.WriteLine(outputString);

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = 0;
        }
    }

它们完全相同,只有一个采用双数组,一个采用int数组,我看到一些例子使用Iconvertible但我无法正确使用语法。有人可以为方法发布一些可行的片段吗?

我怎么称呼它?

编辑:非常感谢答案,我还有一个更复杂的案例,我需要重构,而这里的建议不适用于这两种方法。请点击此链接了解更多详情

How do I refactor these 2 methods? Part 2.

4 个答案:

答案 0 :(得分:5)

将您的代码更改为:

    public static void outputDetail<T>(DateTime previousTime, ref T[] array, System.IO.StreamWriter streamWriter)  //the parameter in here is not necessary, but want to maintain a similiarity in the TimeOfDay class
    {
        string outputString = previousTime.ToString("yyyy/MM/dd");
        Boolean bypass = true;

        for (int i = 1; i < array.Length - 1; i++)
        {
            if (!Object.Equals(array[i], default(T)))
            {
                outputString = outputString + "," + array[i].ToString();
                bypass = false;
            }
            else
            {
                outputString = outputString + ",";
            }
        }
        if (bypass == false)
            streamWriter.WriteLine(outputString);

        Array.Clear(array, 0, array.Length);
    }

发生了什么变化?

首先是方法签名:它接受T类型的通用数组(因此无论是intdoublebool还是{{1}都无关紧要}})。

现在你必须将比较修正为零。零是int和double的默认值,因此您可以使用默认值(T)获取实际类型的默认值,使用strings进行比较(Object.Equals()==运算符不是为通用类型定义。)

最后你只需要清除数组(再次为零),这样你就可以简单地使用!=完成所有工作(而且它甚至比手工制作的Array.Clear()快一点。)

答案 1 :(得分:2)

其他答案都是正确的,使用泛型是最好的,在这里我只是使用Linq为你更清楚地重新编写代码:

public static void outputDetail<T>(DateTime previousTime, ref T[] array, 
                                   StreamWriter streamWriter) where T : struct
{
    if (array.Any(a => !a.Equals(default(T))))
    {
        string outputString = string.Join(",", 
                                          previousTime.ToString("yyyy/MM/dd"),
                                          string.Join(",", array));

        streamWriter.WriteLine(outputString);
    }

    array = Enumerable.Repeat(default(T), array.Length).ToArray();
}

答案 2 :(得分:0)

这应该有效。顺便说一句,连接这样的字符串是GC的负担,看看StringBuilder类。

    public static void outputDetail<T>(DateTime previousTime, ref T[] array, StreamWriter streamWriter)  //the parameter in here is not necessary, but want to maintain a similiarity in the TimeOfDay class
    {
        var outputString = new StringBuilder(previousTime.ToString("yyyy/MM/dd"));
        Boolean bypass = true;

        for (int i = 1; i < array.Length - 1; i++)
        {
            outputString.Append("," + array[i]);

            if (!(array[i].Equals(default(T))))
                bypass = false;
        }
        if (bypass == false)
            streamWriter.WriteLine(outputString);

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = default(T);
        }
    }

答案 3 :(得分:0)

只是一个替代思想,就像在Java中一样,你可以创建一个名为Number的抽象类,其中Integer,Doubles等继承自这个抽象类。然后,您可以将数组替换为数组。这是可扩展的,您可以混合使用类型。

此示例适用于Java,但提供了这个想法。 http://www.daniweb.com/software-development/java/threads/185870/one-method-for-stack-of-either-integer-or-double-parameters

public abstract class Number
{
}



public static void outputDetail(DateTime previousTime, ref Number[] array, StreamWriter streamWriter)  //the parameter in here is not necessary, but want to maintain a similiarity in the TimeOfDay class
{
    string outputString = previousTime.ToString("yyyy/MM/dd");
    Boolean bypass = true;

    for (int i = 1; i < array.Length - 1; i++)
    {
        outputString = outputString + "," + array[i].ToString();

        if (array[i] != 0)
            bypass = false;
    }
    if (bypass == false)
        streamWriter.WriteLine(outputString);

    for (int i = 0; i < array.Length; i++)
    {
        array[i] = 0;
    }
}

以下是关于该主题的有趣讨论。 http://www.dreamincode.net/forums/topic/261696-a-abstract-number-class/