有没有办法避免在短时间内写入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))))
答案 0 :(得分:1)
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))))
答案 1 :(得分:0)
是的,您可以从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
。
答案 2 :(得分:0)
这看起来像缺少字符串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
运算符来处理这种情况。
答案 3 :(得分:0)
我认为最好的选择是将标题逻辑提取为单独的方法。这将使事情更有效,更易读,更可测试。
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));
}