2012-09-27 2 views
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; 
     } 
    } 

они точно такие же, только один берет двойной массив и принимает массив int, я вижу, что в каком-то примере используется Iconvertible, но я не могу получить синтаксис правильно. может ли кто-нибудь опубликовать некоторый рабочий фрагмент для метода pls?как мне реорганизовать эти 2 метода?

как можно назвать это?

EDIT: спасибо большое за ответ, у меня есть еще один более сложный случай, который мне нужен для рефакторинга, и предложение здесь не работает над этими двумя методами. Пожалуйста, нажмите на эту ссылку подробнее

How do I refactor these 2 methods? Part 2.

+1

Вы можете использовать «достаточно новый» динамический ключевое слово для это вместо типа, лично не большой поклонник этого, но это возможность. – Viezevingertjes

+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 (так что это не имеет значения, если это int, double, bool или strings).

Теперь вам нужно исправить сравнение для нуля. Zero - значение по умолчанию для int и double, поэтому вы можете использовать значение по умолчанию (T) для получения значения по умолчанию для фактического типа и Object.Equals() для сравнения (== и != операторы не определены для общих типов).

Наконец, вам просто нужно очистить массив (снова с нулем), чтобы вы могли просто использовать Array.Clear(), чтобы выполнить всю работу (и это даже немного быстрее, чем ручной работы for).

+0

Даже лучше, чем динамический, потому что он работает во время компиляции ;-) Хотя, он работает только потому, что сравнение с 0. Если мы хотим проверить if (array [i] == 1), то это не будет , –

+0

@ xavier да, это действительно ограничено этим случаем (но для сравнения с чем-то другим вы можете использовать IConvertible). В качестве альтернативы вы можете получить значение для сравнения в качестве параметра. –

+0

Я знаю, что это глупый вопрос, но как я могу назвать outputDetail с моей главной? –

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); 
     } 
    } 
0

Просто альтернативная мысль, как и в Java, вы можете создать абстрактный класс с именем номер которого Integer, парные и т.д. унаследовать от этого абстрактного класса. Затем вы можете заменить массив на числовой массив. Это масштабируемо, и вы можете смешивать типы.

Этот пример предназначен для 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/

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(); 
} 
Смежные вопросы