关于 Regex 的并行 foreach 问题
Issue in Parallel foreach regarding Regex
我需要帮助将此 for 循环转换为并行 forloop。
public void spellchecker()
{
Invoke(new MethodInvoker(delegate ()
{
using (Hunspell hunspell = new Hunspell("en_us.aff", "en_US.dic"))
{
foreach (Match match in Regex.Matches(GetRichTextBox().Text, @"\w+"))
{
string word = match.Value;
Font fnt = GetRichTextBox().Font;
Color color;
if (!hunspell.Spell(word))
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Underline);
color = Color.Red;
}
else
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Regular);
color = Color.Black;
}
GetRichTextBox().Select(match.Index, match.Length); // Selecting the matching word.
GetRichTextBox().SelectionColor = color;
GetRichTextBox().SelectionStart = GetRichTextBox().TextLength; // Resetting the selection.
GetRichTextBox().SelectionLength = 0;
}
}
}));
}
这是我尝试实现并行 for 循环时的实现。我一直收到一条错误消息,说“Arguments for method'Parallel.ForEach<TSource>(IEnumereable<TSourcce>,Action<TSource>
)”无法从用法中推断出来
Parallel.ForEach(Regex.Matches(GetRichTextBox().Text, @"\w+"), match => {
string word = match.Value;
Font fnt = GetRichTextBox().Font;
Color color;
if (!hunspell.Spell(word))
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Underline);
color = Color.Red;
}
else
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Regular);
color = Color.Black;
}
GetRichTextBox().Select(match.Index, match.Length); // Selecting the matching word.
GetRichTextBox().SelectionColor = color;
GetRichTextBox().SelectionStart = GetRichTextBox().TextLength; // Resetting the selection.
GetRichTextBox().SelectionLength = 0;
});
Parallel.ForEach() 需要 IEnumerable<T>
作为它的第一个参数。 TSource
必须从该类型参数中推断出来,因为第二个参数是一个 lambda 表达式,其自身参数没有声明类型。 Regex.Matches(string, string) returns MatchCollection
,实现非泛型 System.Collections.IEnumerable
,not IEnumerable<T>
。它早于仿制药。所以编译器无法推断 TSource
是什么。
但我们知道 TSource
应该是 Match
。所以使用 Cast<T>()
:
Parallel.ForEach(Regex.Matches(GetRichTextBox().Text, @"\w+").Cast<Match>(),
match => {
兴趣点
你可以明确地说 lambda 的参数是 Match
:
Parallel.ForEach(Regex.Matches(GetRichTextBox().Text, @"\w+"), (Match match) =>
而且您将不会再收到类型推断错误。但是,您仍然会收到关于 IEnumerable 的错误,因为 MatchCollection
仍然不会实现泛型 IEnumerable<T>
:
error CS1503: Argument 1: cannot convert from 'System.Text.RegularExpressions.MatchCollection' to 'System.Collections.Generic.IEnumerable<System.Text.RegularExpressions.Match>
'
顺便说一句,这就是为什么你不能在 MatchCollection
上的 foreach
中使用 var
而不显式地将循环变量声明为 Match
或将其强制转换为循环体:根据编译器所知,m
是 object
.
foreach (var m in Regex.Matches("foo", "[0-9]"))
{
var caps = m.Captures;
}
error CS1061: 'object' does not contain a definition for 'Captures' and no extension method 'Captures' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
我需要帮助将此 for 循环转换为并行 forloop。
public void spellchecker()
{
Invoke(new MethodInvoker(delegate ()
{
using (Hunspell hunspell = new Hunspell("en_us.aff", "en_US.dic"))
{
foreach (Match match in Regex.Matches(GetRichTextBox().Text, @"\w+"))
{
string word = match.Value;
Font fnt = GetRichTextBox().Font;
Color color;
if (!hunspell.Spell(word))
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Underline);
color = Color.Red;
}
else
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Regular);
color = Color.Black;
}
GetRichTextBox().Select(match.Index, match.Length); // Selecting the matching word.
GetRichTextBox().SelectionColor = color;
GetRichTextBox().SelectionStart = GetRichTextBox().TextLength; // Resetting the selection.
GetRichTextBox().SelectionLength = 0;
}
}
}));
}
这是我尝试实现并行 for 循环时的实现。我一直收到一条错误消息,说“Arguments for method'Parallel.ForEach<TSource>(IEnumereable<TSourcce>,Action<TSource>
)”无法从用法中推断出来
Parallel.ForEach(Regex.Matches(GetRichTextBox().Text, @"\w+"), match => {
string word = match.Value;
Font fnt = GetRichTextBox().Font;
Color color;
if (!hunspell.Spell(word))
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Underline);
color = Color.Red;
}
else
{
fnt = new Font(fnt.FontFamily, fnt.Size, FontStyle.Regular);
color = Color.Black;
}
GetRichTextBox().Select(match.Index, match.Length); // Selecting the matching word.
GetRichTextBox().SelectionColor = color;
GetRichTextBox().SelectionStart = GetRichTextBox().TextLength; // Resetting the selection.
GetRichTextBox().SelectionLength = 0;
});
Parallel.ForEach() 需要 IEnumerable<T>
作为它的第一个参数。 TSource
必须从该类型参数中推断出来,因为第二个参数是一个 lambda 表达式,其自身参数没有声明类型。 Regex.Matches(string, string) returns MatchCollection
,实现非泛型 System.Collections.IEnumerable
,not IEnumerable<T>
。它早于仿制药。所以编译器无法推断 TSource
是什么。
但我们知道 TSource
应该是 Match
。所以使用 Cast<T>()
:
Parallel.ForEach(Regex.Matches(GetRichTextBox().Text, @"\w+").Cast<Match>(),
match => {
兴趣点
你可以明确地说 lambda 的参数是 Match
:
Parallel.ForEach(Regex.Matches(GetRichTextBox().Text, @"\w+"), (Match match) =>
而且您将不会再收到类型推断错误。但是,您仍然会收到关于 IEnumerable 的错误,因为 MatchCollection
仍然不会实现泛型 IEnumerable<T>
:
error CS1503: Argument 1: cannot convert from 'System.Text.RegularExpressions.MatchCollection' to '
System.Collections.Generic.IEnumerable<System.Text.RegularExpressions.Match>
'
顺便说一句,这就是为什么你不能在 MatchCollection
上的 foreach
中使用 var
而不显式地将循环变量声明为 Match
或将其强制转换为循环体:根据编译器所知,m
是 object
.
foreach (var m in Regex.Matches("foo", "[0-9]"))
{
var caps = m.Captures;
}
error CS1061: 'object' does not contain a definition for 'Captures' and no extension method 'Captures' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)