Lambda .Where() expression to return selected/flagged objects In our software we enable certain features based on the existence of a flag.  The Flags class is a static class used to determine the existence of such a flag.

I came across one piece of logic that I wrote that I feel could benefit from refactoring.  The boolean logic works, but I think it's difficult to understand or read because it relies very heavily on short-circuiting.

The basic logic is:


Get all menu items.
Return a subset of those menu items by using the following rule:

Some menu items are tied to a specific flag that is expected to be hard-coded in some way.  The menu item name may not match the associated flag.
Any other menu items should be displayed.



Any help would be much appreciated.

private IEnumerable&lt;MenuItemDefinition&gt; GetMenuItems()
{
     return GetAllMenuItems().Where(mi =&gt; 
          (mi.MethodName != "NewWidget" || Flags.HasFlag("Feature1")) &amp;&amp;
          (mi.MethodName != "NewDongle" || Flags.HasFlag("Feature2")));
}
If you control the MenuItemDefinition class, why not just add a feature tag to it?

public class MenuItemDefinition
{
    public string MethodName { get; set; }
    public string Feature { get; set; }
}

// each instance
new MenuItemDefinition { MethodName = "NewWidget", Feature = "Widgets" }

// GetMenuItems():
return GetAllMenuItems().Where(m =&gt; FeatureIsEnabled(m.Feature));


If not, you could put them in a dictionary:

var items = new Dictionary&lt;string, MenuItemDefinition[]&gt; {
    { "Widgets", new[] {
        new MenuItemDefinition { MethodName = "NewWidget" },
        new MenuItemDefinition { MethodName = "DeleteWidget" }
    },
    { "Default", new[] {
        // ....
    }
}

return items.Where(pair =&gt; FeatureIsEnabled(pair.Key)).SelectMany(pair =&gt; pair.Value);


Or better yet, build the initial list based upon content in a dictionary. That way you don't run the risk of having typos in the switch or the initial setup:

var dict = new Dictionary&lt;string, string[]&gt; 
{
    { "Widgets", new[] { "NewWidget", "DeleteWidget" },
    { "Default", new[] { "..." }
    ...
}

var menuItems = dict
    .Where(p =&gt; FeatureIsEnabled(p.Key))
    .SelectMany(p =&gt; p.Value)
    .Select(mn =&gt; new MenuItemDefinition { MethodName = mn });

// GetMenuItems()
return menuItems; // :)