1
    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;
        }
    }

それらはまったく同じで、1つだけがdouble配列を取り、もう1つはint配列を取ります。いくつかの例では、Iconvertibleを使用していますが、構文を正しく取得できません。誰かがメソッドplsの実行可能なスニペットを投稿できますか?

どうすればいいですか?

編集:答えてくれてありがとう、私はリファクタリングする必要がある別のやや複雑なケースがあります、そしてここでの提案はその2つの方法では機能しません。詳細については、このリンクをクリックしてください

これら2つの方法をリファクタリングするにはどうすればよいですか?パート2。

4

4 に答える 4

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かは関係ありません)。intdoubleboolstrings

ここで、ゼロの比較を修正する必要があります。ゼロはintとdoubleの両方のデフォルト値であるため、default(T)を使用して、実際の型とObject.Equals()比較のためのデフォルト値を取得できます(==および、!=演算子は汎用型に対して定義されていません)。

最後に、配列をクリアする必要があります(これもゼロで)。これによりArray.Clear()、すべての作業を簡単に実行できます(手作りよりも少し速くなりますfor)。

于 2012-09-27T10:12:23.807 に答える
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();
}
于 2012-09-27T10:45:51.683 に答える
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);
        }
    }
于 2012-09-27T10:14:28.183 に答える
0

Javaの場合のように、別の考えとして、Integer、Doublesなどがこの抽象クラスから継承するNumberという名前の抽象クラスを作成できます。次に、その配列を数値配列に置き換えることができます。これはスケーラブルであり、タイプを混在させることができます。

この例はJava用ですが、アイデアを提供します。http://www.daniweb.com/software-development/java/threads/185870/one-method-for-stack-of-ether-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/

于 2012-09-27T10:41:52.307 に答える