【发布时间】:2016-03-16 19:21:44
【问题描述】:
我有一个方法要传入两次,开始和结束。用户可以输入其中一个、两个或一个都不输入。然后我使用 Linq 查询数据库以查找这两次之间的所有记录。当开始和或结束参数为空时,我将如何处理这些情况。如果两者都不为空,则为
where beginning <= time && time <= end
有没有办法不用 if、if else、else 语句就能写出这些情况?
【问题讨论】:
我有一个方法要传入两次,开始和结束。用户可以输入其中一个、两个或一个都不输入。然后我使用 Linq 查询数据库以查找这两次之间的所有记录。当开始和或结束参数为空时,我将如何处理这些情况。如果两者都不为空,则为
where beginning <= time && time <= end
有没有办法不用 if、if else、else 语句就能写出这些情况?
【问题讨论】:
检查输入参数是否为空或输入参数是否匹配条件。
// from and to are user DateTime? inputs
var filtered = myCollection.Where(x =>
(from == null || x.Date >= from) &&
(to == null || x.Date < to));
这适用于所有场景...
from,则返回from之后的所有项目。to,则返回to之前的所有项目。from 和to,则返回from 和to 之间的所有项目。编辑
这要归功于 || 运算符短路。在我的回答中,如果未指定可选参数(from 或 to)(因此 null),则表达式解析为 true,甚至不评估第二个条件。但是,如果它们不为 null,那么也会检查第二个条件。
这是来自 C# 规范的一个 sn-p,I stole from this answer :) 解释了(可能比我能解释的更好)关于短路操作符。
&&和||运算符称为条件逻辑运算符。它们也被称为“短路”逻辑运算符。...
操作
x && y对应于操作x & y,除了y仅在x为true时才被评估
操作x || y对应于操作x | y,除了y仅在x不是true时才被评估。...
操作
x || y被评估为x ? true : y。换句话说,x首先被评估并转换为类型bool。那么,如果x为true,则运算结果为true。否则,y被求值并转换为类型bool,这将成为操作的结果。
【讨论】:
|| 和&& 在 C# 中是短路的。 This answer has a bunch of information from the C# spec, which details how it works.
我做了一个小示范:
将满足您的请求的逻辑表达式是:
(!start.HasValue || start < we.Reception) && (we.Reception < end || !end.HasValue)
意思:
(如果 start 没有 有 value TRUE OR(值小于 ReceptionValue))AND(ReceptionValue 小于 end value OR(end 没有值为 TRUE))
var myTimes = new List<WeddingEvent>()
{
new WeddingEvent { Id = 1, Reception = DateTime.Now.AddHours(-3) },
new WeddingEvent { Id = 2, Reception = DateTime.Now.AddHours(-2) },
new WeddingEvent { Id = 3, Reception = DateTime.Now.AddHours(-1) },
new WeddingEvent { Id = 4, Reception = DateTime.Now.AddHours(0) },
new WeddingEvent { Id = 5, Reception = DateTime.Now.AddHours(1) },
new WeddingEvent { Id = 6, Reception = DateTime.Now.AddHours(2) },
new WeddingEvent { Id = 7, Reception = DateTime.Now.AddHours(3) },
};
DateTime? start = null; //DateTime.Now.AddHours(0.5);
DateTime? end = DateTime.Now.AddHours(3.5);
var weddingInHalfAnHour = myTimes.Where(we => (!start.HasValue || start < we.Reception) && (we.Reception < end || !end.HasValue));
foreach (var wedding in weddingInHalfAnHour)
{
Console.WriteLine("Id: {0} ReceptiontTime: {1}", wedding.Id, wedding.Reception);
}
【讨论】: