2017-02-17 93 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小时内喂食!

相关问题