我想完成以下内容:
(clientSinceChoices = Enumerable.Range(1949, DateTime.Now.Year - 1950)
.Select(x => new SelectListItem()
{
Text = x != 1949 ? x.ToString() : "Unselected",
Value = x != 1949 ? new DateTime(x, 1, 1).ToString() : null,
Selected = () =>
{
if (x == 1949 && !ClientSinceYearOnly.HasValue)
return true;
else if (ClientSinceYearOnly.Value == x)
return true;
else
return false;
}
}));
我希望Selected
的值是内联定义的labmda表达式的结果。我知道我可以通过将lambda分配给变量然后调用它来实现这一点,但我认为定义并立即调用它是“更干净”。
答案 0 :(得分:7)
首先,要实际回答你的问题:你可以通过将lambda强制转换为委托来调用lambda“
bool x = ((Func<bool>) ()=>true) ();
但是在你的代码中,首先不需要lambda;我不明白为什么你有一个lambda。您想计算布尔值,因此计算布尔值:
Selected = (x == 1949 && !ClientSinceYearOnly.HasValue) ||
(ClientSinceYearOnly.Value == x)
(另请注意,在比较之前,您无需检查可空值是否具有值;在C#中,相等性已“提升为可空”。)
其次,这个查询很乱,因为你有一个特殊情况。我不会在第一时间写这样的查询。我宁愿说:
var choices = new List<Item>();
choices.Add(new SelectListItem()
{
Text = "Unselected",
Value = null;
Selected = ClientSinceYearsOnly == null
};
choices.AddRange(
Enumerable.Range(1950, DateTime.Now.Year - 1951)
.Select(x => new SelectListItem()
{
Text = x.ToString(),
Value = new DateTime(x, 1, 1).ToString(),
Selected = x == ClientSinceYearOnly
});
更清楚。或者,给自己写一个扩展方法,将某些内容粘贴到序列的开头:
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> sequence, T first)
{
yield return first;
foreach(T item in sequence)
yield return item;
}
然后:
var choices =
Enumerable.Range(1950, DateTime.Now.Year - 1951)
.Select(x => new SelectListItem()
{
Text = x.ToString(),
Value = new DateTime(x, 1, 1).ToString(),
Selected = x == ClientSinceYearOnly
})
.Prepend(new SelectListItem()
{
Text = "Unselected",
Value = null;
Selected = ClientSinceYearsOnly == null
});
答案 1 :(得分:4)
您总是可以将条件放在方法中并调用:
public static bool ShouldBeSelected(int x)
{
if (x == 1949 && !ClientSinceYearOnly.HasValue)
return true;
else if (ClientSinceYearOnly.Value == x)
return true;
else
return false;
}
然后你可以使用它:
(clientSinceChoices = Enumerable.Range(1949, DateTime.Now.Year - 1950)
.Select(x => new SelectListItem()
{
Text = x != 1949 ? x.ToString() : "Unselected",
Value = x != 1949 ? new DateTime(x, 1, 1).ToString() : null,
Selected = ShouldBeSelected(x)
}));
另外,在你的情况下,你可以使用一系列逻辑运算符,因为你返回一个布尔值(不推荐如果你不希望未来的维护者在你的睡眠中杀死你) :
(x == 1949 && !ClientSinceYearOnly.HasValue) || (ClientSinceYearOnly.Value == x)
答案 2 :(得分:1)
这不是lambda的最佳用法,但是你调用lambda内联的方式就是在它后面添加括号:
(clientSinceChoices = Enumerable.Range(1949, DateTime.Now.Year - 1950)
.Select(x => new SelectListItem()
{
Text = x != 1949 ? x.ToString() : "Unselected",
Value = x != 1949 ? new DateTime(x, 1, 1).ToString() : null,
Selected = ((Func<bool>)(() =>
{
if (x == 1949 && !ClientSinceYearOnly.HasValue)
return true;
else if (ClientSinceYearOnly.Value == x)
return true;
else
return false;
}))() // <-- the () calls the function
}));
答案 3 :(得分:0)
以下代码在功能上是等效的:
Selected =
x == 1949 && !ClientSinceYearOnly.HasValue ||
ClientSinceYearOnly.Value == x;