簡體   English   中英

我可以在列表中使用匿名類型嗎? <T> 而不是幫助類?

[英]Can I use an anonymous type in a List<T> instead of a helper class?

我需要一個包含一些對象的列表進行計算。

我目前的代碼看起來像這樣

private class HelperClass
{
    public DateTime TheDate {get;set;}
    public TimeSpan TheDuration {get;set;}
    public bool Enabled {get;set;}
}

private TimeSpan TheMethod()
{
    // create entries for every date
    var items = new List<HelperClass>();
    foreach(DateTime d in GetAllDatesOrdered())
    {
        items.Add(new HelperClass { TheDate = d, Enabled = GetEnabled(d), });
    }

    // calculate the duration for every entry
    for (int i = 0; i < items.Count; i++)
    {
        var item = items[i];
        if (i == items.Count -1) // the last one
            item.TheDuration = DateTime.Now - item.TheDate;
        else
            item.TheDuration = items[i+1].TheDate - item.TheDate;
    }

    // calculate the total duration and return the result
    var result = TimeSpan.Zero;
    foreach(var item in items.Where(x => x.Enabled))
        result = result.Add(item.TheDuration);
    return result;
}

現在我發現為我的計算引入一個類型(HelperClass)有點難看。 我的第一種方法是使用Tuple<DateTime, TimeSpan, bool>就像我通常這樣做但因為我需要在創建實例后修改TimeSpan,所以我不能使用Tuple,因為Tuple.ItemX是readonly。

我想過一個匿名類型,但我無法弄清楚如何初始化我的列表

var item1 = new { TheDate = DateTime.Now,
                  TheDuration = TimeSpan.Zero, Enabled = true };

var items = new List<?>(); // How to declare this ???
items.Add(item1);

可以使用LINQ執行此操作:

var itemsWithoutDuration = GetAllDatesOrdered()
    .Select(d => new { TheDate = d, Enabled = GetEnabled(d) })
    .ToList();
var items = itemsWithoutDuration
    .Select((it, k) => new { TheDate = it.d, Enabled = it.Enabled, 
         TheDuration = (k == (itemsWithoutDuration.Count - 1) ? DateTime.Now : itemsWithoutDuration[k+1].TheDate) - it.TheDate })
    .ToList();

但到那時, Tuple更具可讀性和簡潔性!

使用投影看起來就像前進的方式 - 但你可以隨時計算持續時間,通過用自己“壓縮”你的集合,偏移一個。 然后,您可以在一個查詢中執行整個方法:

// Materialize the result to avoid computing possibly different sequences
var allDatesAndNow = GetDatesOrdered().Concat(new[] { DateTime.Now })
                                      .ToList();

return allDatesNow.Zip(allDatesNow.Skip(1),
                       (x, y) => new { Enabled = GetEnabled(x),
                                       Duration = y - x })
                  .Where(x => x.Enabled)
                  .Aggregate(TimeSpan.Zero, (t, pair) => t + pair.Duration);

Zip調用將每個日期與其后續日期配對,將每對值轉換為持續時間和啟用標志。 Where調用過濾掉禁用的對。 Aggregate調用對結果對中的持續時間求和。

暫無
暫無

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

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