2014-07-24 64 views
1

我認識到這可能不需要重構。我只是開始嘗試重構,並且我嘗試使用這一行代碼嘗試這樣做失敗。我試圖在VS2013中使用提取方法。唉。我在另外11個實例中使用了這一行的右側。我將如何重構C#中的這一行代碼?

Balance = Enumerable.Repeat(0.0, MonthsToRun).ToList(); 

BalancedoubleMonthsToRunint

每請求:

for (int i = 0, chunksCnt = Chunks.Count; i < chunksCnt; i++) 
    { 
    if (Chunks[i].BeginDate < BeginDate) BeginDate = Chunks[i].BeginDate; 
    MonthsToRun = Math.Max(MonthsToRun, Utils.MonthDifference(BeginDate, Chunks[i].BeginDate) + Chunks[i].Balance.Count); 
    } 

    Balance = Enumerable.Repeat(0.0, MonthsToRun).ToList(); 
    Default = Enumerable.Repeat(0.0, MonthsToRun).ToList(); 
    Loss = Enumerable.Repeat(0.0, MonthsToRun).ToList(); 
    Prepay = Enumerable.Repeat(0.0, MonthsToRun).ToList(); 
    Principal = Enumerable.Repeat(0.0, MonthsToRun).ToList(); 
    Interest = Enumerable.Repeat(0.0, MonthsToRun).ToList(); 

    for (int i = 0, chunksCnt = Chunks.Count; i < chunksCnt; i++) 
     { 
     offset = Utils.MonthDifference(BeginDate, Chunks[i].BeginDate); 

     for (int j = offset, balanceCnt = Chunks[i].Balance.Count; j < (balanceCnt + offset); j++) 
      { 
      Balance[j] += Chunks[i].Balance[j - offset]; 
      Default[j] += Chunks[i].Default[j - offset]; 
      Loss[j] += Chunks[i].Loss[j - offset]; 
      Prepay[j] += Chunks[i].Prepay[j - offset]; 
      Principal[j] += Chunks[i].Principal[j - offset]; 
      Interest[j] += Chunks[i].Interest[j - offset]; 
      } 

      if (Settings.runBacktesting) 
       { 
       foreach (KeyValuePair<Tuple<int, int, DateTime>, double> item in Chunks[i].TransProbChunk) 
       { 
       Utils.upsertDict(TransProbAgg, item.Key, item.Value); 
       //Create From Status - Month Totals Dictionary to create transition rates 
       Tuple<int, DateTime> key = new Tuple<int, DateTime>(item.Key.Item1, item.Key.Item3); 
       Utils.upsertDict(fromMonthTotals, key, item.Value); 
       } 
      } 
     } 
+2

爲什麼你認爲這需要重構? _「平衡是雙重的」_否,那麼這將不會編譯。也許一個'清單'。 –

+1

您通常不會在行級重構,而是概念化(類,接口等)級別。但是,如果您看到一個在整個代碼中使用很多的模式,請嘗試描述它。 – Groo

+0

這更讓我的腳溼潤。它可能不會。我只是好奇,假設它確實需要重構,那麼這將是一個合適的方式。 – StephenWinburn

回答

1

我個人不覺得有必要重構該行。 重構通常是因爲可讀性/理解性或性能。 該行似乎是可讀的。

如果因爲重複而試圖重構,那麼你會重構以下內容,因爲'= 0;'重複?

int x1 = 0; 
int x2 = 0; 
int x3 = 0; 
int x4 = 0; 
int x5 = 0; 
int x6 = 0; 
int x7 = 0; 

在這個愚蠢的情況下,你可以把它放在一行,但在真實的代碼中,它將變得不可讀。

你可以做的是使一個方法是「零」中的變量:

private void Zero<T>(int size, ref List<T> l1, ref List<T> l2, ref List<T> l3) 
    { 
     T[] zeroes = Enumerable.Repeat(default(T), size).ToArray(); 
     l1 = new List<T>(zeroes); 
     l2 = new List<T>(zeroes); 
     l3 = new List<T>(zeroes); 
    } 

,並調用它像:

Zero(MonthsToRun, ref Balance, ref Default, ref Loss, ...); 

如果你正在嘗試做的,因爲性能,然後一些類型的緩存可以幫助你......

public static class Sizer<T> 
{ 
    static Dictionary<int, T[]> _cache = new Dictionary<int, T[]>(); 

    public static void Init(ref List<T> list, int size) 
    { 
     T[] ret; 

     if (!_cache.TryGetValue(size, out ret)) 
     { 
      ret = Enumerable.Repeat(default(T), size).ToArray(); 
      _cache[size] = ret; 
     } 

     list = ret.ToList(); 
    } 
} 

Altough我不認爲你能達到多少與它...

下面與上述類告訴(我也沒在意優化)的增速大約是6倍:

 Random r; 
     const int repeatCount = 1000000; 
     List<int> list = null; 

     r = new Random(0); 
     var start = DateTime.Now.Ticks; 
     for (int i = 0; i < repeatCount; i++) 
     { 
      list = Enumerable.Repeat(0, r.Next(5,150)).ToList(); 
     } 
     var end = DateTime.Now.Ticks; 
     var t1 = end - start; 

     r = new Random(0); 
     start = DateTime.Now.Ticks; 
     for (int i = 0; i < repeatCount; i++) 
     { 
      Sizer<int>.Init(ref list, r.Next(5, 150)); // fill the list with default values for the type 
     } 
     end = DateTime.Now.Ticks; 
     var t2 = end - start; 
     var speedup = (double)t1/t2; 
+0

謝謝你的徹底。 – StephenWinburn

0

正如其他人提到你操作的結果是雙打的名單。 如果你有十一行你使用Enumerable.Repeat並且至少有一個參數每行不一樣,那麼編寫一個函數(也許是一個內聯函數)是有意義的,但是我會這樣做,因爲它足夠簡單並且易於理解。

如果您需要讓我們在11個地方列出n零,然後創建一個數組並在需要的地方使用它。

var zeroes = Enumberable.Repeat(0.0 ,MonthsToRun).ToArray(); 
//or even: 
//var zeroes = new double[MonthsToRun]; 
... 
var myList1 = new List<double>(zeroes); 
... 
var myList2 = new List<double>(zeroes); 

內聯函數中使用的快捷鍵:

Func<double, int, List<double>> rv = (val, count) => { return Enumerable.Repeat(val, count).ToList(); }; 
... 
var myList1 = rv(0.0, MonthsToRun); 
... 

此外,如果你用錢的工作,然後用decimal工作:

decimal vs double! - Which one should I use and when?

+0

謝謝你的想法。 – StephenWinburn