首页 文章

关于正则表达式的并行foreach问题

提问于
浏览
-2

我需要帮助将这个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;
});

1 回答

  • 4

    Parallel.ForEach()想要 IEnumerable<T> 作为它的第一个参数 . 必须从该类型参数推断 TSource ,因为第二个参数是一个lambda表达式,其自身参数没有声明的类型 . Regex.Matches(string, string)返回 MatchCollection ,它实现非泛型 System.Collections.IEnumerable ,而不是 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>

    错误CS1503:参数1:无法从'System.Text.RegularExpressions.MatchCollection'转换为'System.Collections.Generic.IEnumerable <System.Text.RegularExpressions.Match>'


    顺便说一下,这就是为什么你不能在 foreachforeach 中使用 var 而不明确地将循环变量声明为 Match 或将其转换为循环体:基于编译器知道的所有内容, mobject .

    foreach (var m in Regex.Matches("foo", "[0-9]"))
    {
        var caps = m.Captures;
    }
    

    错误CS1061:'object'不包含'Captures'的定义,也没有扩展方法'Captures'接受'object'类型的第一个参数(你是否缺少using指令或汇编引用?)

相关问题