3
\$\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\$
1
  • 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\$ Commented Jun 17, 2017 at 10:25

1 Answer 1

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\$
2
  • \$\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
    Commented Jun 18, 2017 at 8:21
  • \$\begingroup\$ Nice work, I'll update the post. \$\endgroup\$
    – mjwills
    Commented Jun 18, 2017 at 9:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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