MatchEvaluator gives “Cannot use a lambda expressi

2019-09-21 17:19发布

问题:

I'm modifying the contents of several files. I have this Regex in a form and it's called directly from a button's click event.

public partial class MainForm : Form
{
    private void UpdateButton_Click(object sender, EventArgs e)
    {
        // code

        if (!OldURLBox.Text.IsEmpty() && !NewURLBox.Text.IsEmpty())
        {
            Regex patternURL = new Regex(string.Format("s:\\d+:\\\\\"((.(?!s:\\d+))*?){0}(.*?)\\\\\";", OldURL));
            content = patternURL.Replace(content, delegate(Match m) // works fine
            {
                var prefix = m.Groups[1].Value;
                var postfix = m.Groups[3].Value;
                var length_prefix = prefix.Replace("\\n", "$").Length;
                var length_postfix = postfix.Replace("\\n", "$").Length;
                var length_total = length_prefix + NewURL.Length + length_postfix;
                return string.Format("s:{0}:\\\"{1}{2}{3}\\\";", length_total, prefix, NewURL, postfix);
            });
        }

        // code
    }
}

This is working fine. I've moved this code (regex replace) to another project and getting the following error:

Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type

I'm not calling the regex replace directly inside an event function and I guess that's what causing the error. I don't know how to fix it. Examine the following code. This is the structure I'm using. Omitted irrevelant parts.

public partial class ProgressForm : Form
{
    private void ProgressForm_Load(object sender, EventArgs e)
    {
        // when run without delay, it freezes, waits for targz extraction
        System.Timers.Timer timer = new System.Timers.Timer(500);
        timer.Elapsed += (sender2, e2) => OnTimedEvent(sender2, e2);
        timer.AutoReset = false;
        timer.Enabled = true;
    }

    private void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        this.BeginInvoke((MethodInvoker)delegate
        {
            if (File.Exists(Template.File.ArchiveTarGz))
            {
                // code; extract files from archive

                ModifyFiles();

                // code; repack files
            }
        });
    }

    private void ModifyFiles()
    {
        // code

        Regex patternURL = new Regex(string.Format("s:\\d+:\\\\\"((.(?!s:\\d+))*?){0}(.*?)\\\\\";", Template.Website.URL));
        DBText = patternURL.Replace(DBText, delegate(Match m) // Error: Cannot use a lambda expression as an argument ...
        {
           var prefix = m.Groups[1].Value;
           var postfix = m.Groups[3].Value;
           var length_prefix = prefix.Replace("\\n", "$").Length;
           var length_postfix = postfix.Replace("\\n", "$").Length;
           var length_total = length_prefix + UserInput.Website.URL.Length + length_postfix;
           return string.Format("s:{0}:\\\"{1}{2}{3}\\\";", length_total, prefix, UserInput.Website.URL, postfix);
        });

        // code
    }
}

This might be a duplicate, because there are other questions with this exact error, but I couldn't find something that I can implement in my code.

Someone can change the title to a more suitable one. I didn't want the title to be the error because several questions already exist with that.

回答1:

You are replacing the contents of DBText. Regex.replace expectes a string as first argument. I am guessing DBText is of type dynamic, which confuses the compiler in this particular case.

You can simply cast DbText to string and you should be fine

patternURL.Replace((string)DBText, (...)