我该如何用c#重构这行代码呢?
本文关键字:代码 重构 何用 | 更新日期: 2023-09-27 18:14:30
我知道这可能不需要重构。我只是开始尝试重构,但这一行代码的尝试失败了。我尝试在VS2013中使用提取方法。唉。在其他11个例子中,我使用了这一行的右手边。
Balance = Enumerable.Repeat(0.0, MonthsToRun).ToList();
Balance
为double
, MonthsToRun
为int
。
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
0的列表,那么创建一个数组并在需要的地方使用它。
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!-我应该用哪一个,什么时候用?