patterncsharpMinor
Lambda .Where() expression to return selected/flagged objects
Viewed 0 times
expressionobjectsreturnwhereselectedflaggedlambda
Problem
In our software we enable certain features based on the existence of a flag. The
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:
Any help would be much appreciated.
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 GetMenuItems()
{
return GetAllMenuItems().Where(mi =>
(mi.MethodName != "NewWidget" || Flags.HasFlag("Feature1")) &&
(mi.MethodName != "NewDongle" || Flags.HasFlag("Feature2")));
}Solution
If you control the MenuItemDefinition class, why not just add a feature tag to it?
If not, you could put them in a dictionary:
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:
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 => FeatureIsEnabled(m.Feature));If not, you could put them in a dictionary:
var items = new Dictionary {
{ "Widgets", new[] {
new MenuItemDefinition { MethodName = "NewWidget" },
new MenuItemDefinition { MethodName = "DeleteWidget" }
},
{ "Default", new[] {
// ....
}
}
return items.Where(pair => FeatureIsEnabled(pair.Key)).SelectMany(pair => 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
{
{ "Widgets", new[] { "NewWidget", "DeleteWidget" },
{ "Default", new[] { "..." }
...
}
var menuItems = dict
.Where(p => FeatureIsEnabled(p.Key))
.SelectMany(p => p.Value)
.Select(mn => new MenuItemDefinition { MethodName = mn });
// GetMenuItems()
return menuItems; // :)Code Snippets
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 => FeatureIsEnabled(m.Feature));var items = new Dictionary<string, MenuItemDefinition[]> {
{ "Widgets", new[] {
new MenuItemDefinition { MethodName = "NewWidget" },
new MenuItemDefinition { MethodName = "DeleteWidget" }
},
{ "Default", new[] {
// ....
}
}
return items.Where(pair => FeatureIsEnabled(pair.Key)).SelectMany(pair => pair.Value);var dict = new Dictionary<string, string[]>
{
{ "Widgets", new[] { "NewWidget", "DeleteWidget" },
{ "Default", new[] { "..." }
...
}
var menuItems = dict
.Where(p => FeatureIsEnabled(p.Key))
.SelectMany(p => p.Value)
.Select(mn => new MenuItemDefinition { MethodName = mn });
// GetMenuItems()
return menuItems; // :)Context
StackExchange Code Review Q#8264, answer score: 3
Revisions (0)
No revisions yet.