2
\$\begingroup\$

I'm refactoring a WinForms utility program for building and testing regular expressions. The program has a menu item which lists the RegexOptions enumeration, allows the user to checkmark the items they want, and then those settings are applied during regex testing.

WinForms menu populated with RegexOptions

I'm rather new to LINQ, and I'd like to learn the best way to do this. At present the differences between .Cast<> and .OfType<>, .Where() and .Any() and .All() are rather ambiguous to me.

This is the code I'm using to load the menu-

menuRegexOptions.MenuItems.AddRange(
    Enum
    .GetValues(typeof(RegexOptions))
    .Cast<RegexOptions>()
    .Where(
        s => s != RegexOptions.None
    )
    .Select(
        p => new MenuItem(null, option_Click)
        {
            Text = p.ToString(),
            Tag = p
        })
    .ToArray()
    );

It works and is readable, but I'm keen to know if I've missed any fundamentals or can make it more efficient.

To determine the current Regex setting, the checkmarked menu items must be combined using a bitwise OR operation. The best solution I could come up with is-

public RegexOptions SelectedRegexOptions
{
    get
    {
        RegexOptions options = RegexOptions.None;

        mnuRegexOptions.MenuItems
            .Cast<MenuItem>()
            .Where(
                x => x.Checked 
            )
            .ToList()
            .ForEach(
                s => {
                    options |= (RegexOptions)s.Tag;
                } 
            );

        return options; 
    }
}

It works, but it feels like I should be able to do the != operation internally to the LINQ and then simply return the result, without the need for the external options variable.

Is there a better way?

\$\endgroup\$

migrated from stackoverflow.com Jun 26 '17 at 18:16

This question came from our site for professional and enthusiast programmers.

  • 1
    \$\begingroup\$ are rather ambiguous to me -- The documentation isn't. Best thing you can do is to work through a couple of simple examples to get this stuff into your DNA. You won't regret it. \$\endgroup\$ – Gert Arnold Jun 17 '17 at 10:25
4
\$\begingroup\$

Try this:

public RegexOptions SelectedRegexOptions
{
    get
    {
       RegexOptions options = mnuRegexOptions.MenuItems
            .Cast<MenuItem>()
            .Where(
                x => x.Checked 
            )
            .Select(s => (RegexOptions)s.Tag)
            .Aggregate(RegexOptions.None, (x, y) => x | y);

        return options; 
    }
}

The Aggregate call will take care of the bitwise ORs.

\$\endgroup\$
  • \$\begingroup\$ Excellent, that's exactly what I needed. It seems Aggregate fails if the Select returns an empty list, so I've adjusted it to use the seeded version. .Aggregate(RegexOptions.None, (x, y) => x | y); \$\endgroup\$ – Memetican Jun 18 '17 at 8:21
  • \$\begingroup\$ Nice work, I'll update the post. \$\endgroup\$ – mjwills Jun 18 '17 at 9:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.