2017-02-17 66 views
0

所以示例程序:有沒有辦法避免依賴於表達式的linq投影重複?

class Cat 
    { 
     public bool IsMale { get; set;} 
     public int TailLength { get; set; } 
     public string Name { get; set; } 
     public decimal ClawAttackFrequency { get; set; } 
     public List<DateTime> FeedingTimes { get; set; } 
    } 


    static void Main(string[] args) 
    { 
     var cats = new List<Cat>(); 
     var someData = cats 
      .Select(x => new 
      { 
       x.Name, 
       x.IsMale, 
       LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y) 
      }) 
      .Select(x => new 
      { 
       x.Name, 
       x.IsMale, 
       x.LatestFeedingTime, 
       WasFedRecently = x.LatestFeedingTime.HasValue && x.LatestFeedingTime.Value >= DateTime.Today.AddDays(-1) 
      }); 
    } 

這僅僅是一個玩具的程序,做什麼,但它說明我的問題是,爲了避免重複我得反而讓兩個突出的LatestFeedingTime表達和複製一堆屬性。

的選擇將是:

var someData = cats 
     .Select(x => new 
     { 
      x.Name, 
      x.IsMale, 
      LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y), 
      WasFedRecently = (x.FeedingTimes.Max(y => (DateTime?)y)).HasValue && (x.FeedingTimes.Max(y => (DateTime?)y)).Value >= DateTime.Today.AddDays(-1) 
     }); 

但這複製一個棘手的表達式來代替。

有沒有什麼辦法在c#中獲得兩全其美的好處。就像一種聲明表達式的方法,然後在相同的投影中使用兩次?

+0

我現在看到幾個答案後,我過分簡化了我的例子。真正的問題更多地與linq相關。我會接受其中一個答案,以防有人真的想知道這個問題,也許會提出一個更好的問題。 – alun

回答

1

我想看看這樣做它這樣:

var someData = 
    from x in cats 
    let LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y) 
    select new 
    { 
     x.Name, 
     x.IsMale, 
     LatestFeedingTime, 
     WasFedRecently = 
      LatestFeedingTime.HasValue 
      && LatestFeedingTime.Value >= DateTime.Today.AddDays(-1) 
    }; 

它肯定消除了你的代碼中的重複,但是它仍然生成相同的代碼。

你甚至可以縮短到這一點:

var someData = 
    from x in cats 
    let LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y) 
    select new 
    { 
     x.Name, 
     x.IsMale, 
     LatestFeedingTime, 
     WasFedRecently = LatestFeedingTime >= DateTime.Today.AddDays(-1) 
    } 
0

您可以簡單地定義一個Build方法返回你希望的東西

var someData = cats 
     .Select (Cat.BuildData); 

而且裏面你

public static Something BuildData (Cat cat) { 

你可以使用任何局部變量...

0

只需使用一個聲明拉姆達在那裏你可以使用局部變量

var someCats = cats.Select(x => 
{ 
    var lft = x.FeedingTimes.Max(y => (DateTime?)y); 
    return new 
    { 
     x.Name, 
     x.IsMale, 
     LatestFeedingTime = lft, 
     WasFedRecently = lft >= DateTime.Today.AddDays(-1) 
    }; 
}); 

但我覺得對不起你的貓,如果你認爲它是最近有可能在過去的48小時內餵食!

相關問題