我是使用lamda expressions
的新手,并且正在尝试弄清楚一些事情。
我创建了以下代码部分,该代码返回日志文件的文件路径。
public static string GetLogFile()
{
var fileTarget = LogManager.Configuration.AllTargets.Where(t=>t.Name == "LogName") as FileTarget;
return fileTarget == null ? string.Empty : fileTarget.FileName.Render(new LogEventInfo { Level = LogLevel.Info });
}
我的问题是,fileTarget
在我使用时为空:
LogManager.Configuration.AllTargets.Where(t=>t.Name == "LogName")
但是如果我将代码行更改为
LogManager.Configuration.AllTargets.FirstOrDefault(t=>t.Name == "LogName")
返回我的日志文件的正确路径。有人可以向我解释Where
和FirstOrDefault
之间是否有主要区别吗?
答案 0 :(得分:2)
在您的情况下,Where
返回对象IEnumerable
的{{1}}(简称为列表)。然后,将此列表转换为FileTarget
。这就是为什么它为空。
但是FileTarget
返回一个对象或FirstOrDefault
,并且可以强制转换为您的类null
。这就是为什么它起作用。
答案 1 :(得分:2)
实际返回IEnumerable的地方(智能会告诉您这一点)。它不知道您的谓词可能匹配多少个项目。 FirstOrDefault将获取第一项或与谓词匹配的第一项。如果您通过了。
(Nb。谓词是接受对象并返回布尔值的任何函数,有一个称为Predicate<T>
的.Net类型代表它)
使用OfType linq运算符以及null传播和null合并运算符
public static string GetLogFile()
{
var fileTarget = LogManager.Configuration.AllTargets.OfType<FileTarget>().FirstOrDefault(t=>t.Name == "LogName");
return fileTarget?.FileName.Render(new LogEventInfo { Level = LogLevel.Info }) ?? string.Empty;
}
答案 2 :(得分:1)
简单地说,
Where
将为您提供枚举。不会为null。如果谓词中没有匹配项,则为空。
FirstOrDefault
将为您提供一个对象。如果没有匹配项,则为null。
按照您的代码进行操作,它将引发编译错误,表明它无法从IEnumerable转换为FileTarget。