簡體   English   中英

如何在C#中重構這一行代碼?

[英]How would I refactor this line of code in C#?

我認識到這可能不需要重構。 我只是開始嘗試使用重構,而我嘗試使用這一行代碼失敗。 我試圖在VS2013中使用提取方法。 唉。 在其他11種情況下,我將使用此行的右側。

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

Balancedouble MonthsToRunMonthsToRunint

每個請求:

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

我個人不認為需要重構該行。 重構通常是由於可讀性/理解力或性能。 該行似乎是可讀的。

如果由於重復而嘗試重構,那么您將重構以下內容,因為'= 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();
    }
}

雖然我認為您不能用它取得很大的成就...

以下是上述類(我不太在意優化)的說明,加速比約為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;

正如其他人提到的,您的操作結果是雙打列表。 如果您有11行使用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

十進制與雙精度! -應該使用哪一個?何時使用?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM