给定以下源数据:
Dim inputs = {New With {.Name="Bob", .Date="201405030500"},
New With {.Name="Sally", .Date="201412302330"},
New With {.Name="Invalid", .Date="201430300000"}}
我编写了以下LINQ查询(目的是Where success
在之前添加一个子句作为过滤器Select
,但我将其省略,并包含success
在结果中以进行调试):
Dim result1 = From i in inputs
Let newDate = New DateTime
Let success = DateTime.TryParseExact(i.Date, "yyyyMMddHHmm", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.AssumeLocal, newDate)
Select New With {
.Name = i.Name,
.Success = success,
.Date = newDate
}
但是,我得到以下结果,并newDate
没有填充TryParseExact
:
因此,我重构了查询以将提取TryParseExact
到匿名方法中以获取以下信息:
Dim parseDate = Function(d As String)
Dim parsedDate As DateTime
Return New Tuple(Of Boolean, Date)(DateTime.TryParseExact(d, "yyyyMMddHHmm", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.AssumeLocal, parsedDate), parsedDate)
End Function
Dim result2 = From i in inputs
Let parsedDate = parseDate(i.Date)
Select New With {
.Name = i.Name,
.Success = parsedDate.Item1,
.Date = parsedDate.Item2
}
...这正确地给了我:
但是,我想找到一种完全在LINQ语句中完成此操作的方法,而无需使用匿名方法创建元组。当然,我有一些行之有效的方法,但我希望以此为学术兴趣。
我怀疑这是可能的,但我的问题是:
为什么result1
查询没有正确设置newDate
解析日期?
(我考虑过懒惰的评估,但我认为它不适用于这里。)
更新:
由于以下答案,我将LINQ重构如下(包括Where
子句过滤器):
Dim result3 = From i in inputs
Let parsedDate = Function(d)
Dim dtParsed As DateTime
Return If(DateTime.TryParseExact(d, "yyyyMMddHHmm", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.AssumeLocal, dtParsed), dtParsed, New DateTime?)
End Function(i.Date)
Where parsedDate.HasValue
Select New With {
.Name = i.Name,
.Date = parsedDate.Value
}
这样可以达到我想要的目的,并且我相信编译器可以优化生成的代码,但是我仍然想确切地了解为什么result1
不起作用。也许这是埃里克·利珀特(Eric Lippert)或约翰·斯基特(John Skeet)的问题。
我建议您使用TryParsers库,该库是专门为TryParse
在LINQ查询中使用方法而创建的。
Dim query = From i In inputs
Let d = TryParsers.TryParse.DateTimeExact(i.Date, "yyyyMMddHHmm", Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.AssumeLocal)
Select New With {
.Name = i.Name,
.Success = Not d Is Nothing,
.Date = d.Value
}
您不能将范围变量(let
)用作ref / out参数,因为let
关键字创建了一个只读变量(实际上它会编译为匿名对象的属性)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句