C# Regex.Matches 和可空性问题
C# Regex.Matches and nullability issue
我正在使用启用了 nullable
的 C# 8,现在我的正则表达式循环出现问题:
public static async Task<IEnumerable<WorkerDto>?> GetOwnersAsync(LampContext context, string? ownerString)
{
if (string.IsNullOrWhiteSpace(ownerString))
return null;
var wwids = new List<int>();
var matches = Regex.Matches(ownerString, @"\d+");
foreach (Match match in matches)
wwids.Add(int.Parse(match.Value));
它说我可能对 match
迭代变量进行了空引用赋值,我不确定为什么会这样说,或者如何绕过它。 Matches 的文档说它将 return 一个空集合,而不是 null。
我现在应该如何编写该代码?
问题是 MatchCollection
优先于通用 IList<Match>
接口实现非通用 IList
接口,为了向后兼容,IEnumerator.Current
定义为object?
,因此 foreach
实际上将此可为 null 的对象强制转换为不可为 null 的 Match
。就好像你写了
foreach (object o? in matches) {
Match match = (Match) o;
...
}
所有这些都来自我们拥有 C# 2 之前被遗忘已久的时间,现在又回来咬我们的 C# 8。
有几种有效的解决方法;最简单的方法之一是将 matches
分配给 IList<Match>
或 IEnumerable<Match>
类型的变量(因为它确实实现了通用接口):
IList<Match> matches = Regex.Matches(ownerString, @"\d+");
foreach (Match match in matches)
wwids.Add(int.Parse(match.Value));
请注意,我们在这里不需要强制转换。另一种是使用.AsEnumerable()
来有效地施放它:
var matches = Regex.Matches(ownerString, @"\d+");
foreach (Match match in matches.AsEnumerable())
wwids.Add(int.Parse(match.Value));
最后但同样重要的是,如果您所做的只是 .Add
将这些值添加到一个新列表中,您不妨使用 LINQ 一次性构建该列表:
var wwids = matches.Select(m => int.Parse(m.Value)).ToList();
我正在使用启用了 nullable
的 C# 8,现在我的正则表达式循环出现问题:
public static async Task<IEnumerable<WorkerDto>?> GetOwnersAsync(LampContext context, string? ownerString)
{
if (string.IsNullOrWhiteSpace(ownerString))
return null;
var wwids = new List<int>();
var matches = Regex.Matches(ownerString, @"\d+");
foreach (Match match in matches)
wwids.Add(int.Parse(match.Value));
它说我可能对 match
迭代变量进行了空引用赋值,我不确定为什么会这样说,或者如何绕过它。 Matches 的文档说它将 return 一个空集合,而不是 null。
我现在应该如何编写该代码?
问题是 MatchCollection
优先于通用 IList<Match>
接口实现非通用 IList
接口,为了向后兼容,IEnumerator.Current
定义为object?
,因此 foreach
实际上将此可为 null 的对象强制转换为不可为 null 的 Match
。就好像你写了
foreach (object o? in matches) {
Match match = (Match) o;
...
}
所有这些都来自我们拥有 C# 2 之前被遗忘已久的时间,现在又回来咬我们的 C# 8。
有几种有效的解决方法;最简单的方法之一是将 matches
分配给 IList<Match>
或 IEnumerable<Match>
类型的变量(因为它确实实现了通用接口):
IList<Match> matches = Regex.Matches(ownerString, @"\d+");
foreach (Match match in matches)
wwids.Add(int.Parse(match.Value));
请注意,我们在这里不需要强制转换。另一种是使用.AsEnumerable()
来有效地施放它:
var matches = Regex.Matches(ownerString, @"\d+");
foreach (Match match in matches.AsEnumerable())
wwids.Add(int.Parse(match.Value));
最后但同样重要的是,如果您所做的只是 .Add
将这些值添加到一个新列表中,您不妨使用 LINQ 一次性构建该列表:
var wwids = matches.Select(m => int.Parse(m.Value)).ToList();