C# 在依赖于表达式的linq投影中是否有避免重复的方法?
因此,示例程序:C# 在依赖于表达式的linq投影中是否有避免重复的方法?,c#,linq,C#,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> Fee
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)
});
}
但这却复制了一个棘手的表达式
有没有办法在c#中两全其美。像是声明一个表达式,然后在同一个投影中使用两次 您可以简单地定义一个生成方法,返回您想要的内容
var someData = cats
.Select (Cat.BuildData);
在你的内心
public static Something BuildData (Cat cat) {
您可以使用任何局部变量…我会这样做:
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)
}
只要使用lambda语句,就可以使用局部变量
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小时里有可能被喂食,我会为你的猫感到难过! 在回答了几个问题后,我发现我过于简化了我的例子。真正的问题更多地与linq到实体有关。我会接受其中一个答案,以防有人真的对此感到疑惑,也许会发布一个更好的问题。
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)
};
});