C# Lamda表达式,其中VS FirstOrDefault
我刚开始使用C# Lamda表达式,其中VS FirstOrDefault,c#,lambda,C#,Lambda,我刚开始使用lamda表达式,我正在尝试解决一些问题。 我已经创建了下面的代码部分,该代码返回日志文件的文件路径 public static string GetLogFile() { var fileTarget = LogManager.Configuration.AllTargets.Where(t=>t.Name == "LogName") as FileTarget; return fileTarget == null ? string.E
lamda表达式
,我正在尝试解决一些问题。
我已经创建了下面的代码部分,该代码返回日志文件的文件路径
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
之间是否有重大区别吗?在您的例子中,Where
返回对象文件目标的IEnumerable
(简单的列表)。然后,将此列表强制转换为FileTarget
。这就是为什么它是空的
但是FirstOrDefault
返回一个对象或null
,并且可以对类FileTarget
强制转换。这就是它工作的原因。其中实际返回IEnumerable(intellisense将告诉您这一点)。它不知道谓词可能匹配多少项。FirstOrDefault将获取第一项,或与谓词匹配的第一项。如果你通过了
(注意:谓词是任何接受对象并返回bool的函数,有一个名为谓词的.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;
}
public静态字符串GetLogFile()
{
var fileTarget=LogManager.Configuration.AllTargets.OfType().FirstOrDefault(t=>t.Name==“LogName”);
返回fileTarget?.FileName.Render(新的LogEventInfo{Level=LogLevel.Info})?string.Empty;
}
简单地说
其中
将为您提供可枚举的。将不会为空。如果谓词中没有匹配项,则为空。
FirstOrDefault
将为您提供一个对象。如果没有匹配项,则为Null
根据您的代码,它应该抛出一个编译错误,说明它无法从IEnumerable转换为FileTarget。是的,其中
返回一个IEnumerable
。当您尝试将其强制转换为as
时,它将返回null
;但是FirstOrDefault
返回一个可以强制转换的实例。其中可以读取为给我所有记录,其中name==“LogName”
。FirstOrDefault-给我第一条记录,其中name==“LogName”如果没有-给我null
在使用值作为施法时要小心。如果您希望您的值属于该类型,那么请使用()value
“在您的情况下,其中返回IEnumerable”,是否存在不正确的情况?另外,IEnumerable
也不是一个列表。公平地说,@Camilo,IEnumerable
也不是一个真正的列表。这只是一个可以迭代的承诺。例如,您可以将传入的TCP流公开为IEnumerable
,它肯定不是列表,并且可能永远不会结束。语义学可能不太重要,但相当关键。@AntoineV我也没有写列表
,所以我不知道该注释回答了什么。不,它不会引发编译错误,这不是x as y
转换的工作原理。