如何避免在短If中重复Lambda表达式
本文关键字:Lambda 表达式 If 何避免 | 更新日期: 2023-09-27 18:06:45
是否有一种方法可以避免在短if内两次编写lambda表达式?我经常发现自己处于这种情况,我知道的唯一方法就是再写一遍!
为了给出一个例子,这里有一个我需要检查字符串长度的例子!
communications.Select(c => new XElement("node",
new XAttribute("guid", Guid.NewGuid()),
new XAttribute("title", c.CommunicationDetails.Where(x => x.CultureCode == culture).FirstOrDefault().Title.Length < 40 ? c.CommunicationDetails.Where(x => x.CultureCode == culture).FirstOrDefault().Title : c.CommunicationDetails.Where(x => x.CultureCode == culture).FirstOrDefault().Title.Substring(0, 40)),
new XAttribute("isHidden", false))))
Func<IEnumerable<CommunicationDetails>, string> getFirstDtlTitle = ((dtls) => dtls.Where(x => x.CultureCode == culture).FirstOrDefault()?.Title ?? "");
communications.Select(c => new XElement("node",
new XAttribute("guid", Guid.NewGuid()),
new XAttribute("title", getFirstDtlTitle(c.CommunicationDetails).Length < 40 ? getFirstDtlTitle(c.CommunicationDetails) : getFirstDtlTitle(c.CommunicationDetails).Substring(0, 40)),
new XAttribute("isHidden", false))))
将是重构的第一步。
虽然我也会为字符串做一个扩展方法来修剪到最大长度,所以你只需要调用一次lambda。
你会得到这样的结果
Func<IEnumerable<CommunicationDetails>, string> getFirstDtlTitle = ((dtls) => dtls.Where(x => x.CultureCode == culture).FirstOrDefault()?.Title ?? "");
communications.Select(c => new XElement("node",
new XAttribute("guid", Guid.NewGuid()),
new XAttribute("title", getFirstDtlTitle(c.CommunicationDetails).TrimToLength(40),
new XAttribute("isHidden", false))))
是的,您可以从string
是IEnumerable<char>
的事实中获益:
new string(Title.Take(40).ToArray()) //Take will take 40 first elements or as many as there are if less than 40.
或
string.Concat(Title.Take(40))
可能没有那么高性能,但是可读性更强,并且由于代码重复而更少出错。
如前所述,FisrtOrDefault().Title
是等待发生的NullReferenceException
。
这看起来像是缺少字符串API的情况。编写一个方法,允许您传递一个字符串,并接受最多40个字符:
static class StringExtensions {
public static SubstringUpTo(this string str, int len) {
if (str == null) {
return null;
}
if (len < 0) {
throw new ArgumentException(nameof(len));
}
return len >= str.Length ? str : str.Substring(0, len);
}
}
这可以避免第二次获得字符串:
new XAttribute(
"title"
, c.CommunicationDetails.FirstOrDefault(x => x.CultureCode == culture)
?.Title.SubstringUpTo(40)
)
注意使用?.
运算符来处理没有需要的CultureCode
项的情况,null
在SubstringUpTo
扩展方法内处理。
我认为最好的选择是提取标题逻辑分离方法。这将使程序更高效,更易读,更易测试。
communications.Select(c => new XElement("node",
new XAttribute("guid", Guid.NewGuid()),
new XAttribute("title", BuildTitle(c)),
new XAttribute("isHidden", false))))
private string BuildTitle(CommuncationDetails c)
{
var culturedDetails = c.CommunicationDetails.Where(x => x.CultureCode == culture).FirstOrDefault();
if (culturedDetails == null || string.IsNullOrEmpty(culturedDetails.Title)) return string.Empty;
return culturedDetails.Title.Substring(0, Math.Min(40, culturedDetails.Title.Length));
}