patterncsharpMinor
Setting enum flags by string (in any order)
Viewed 0 times
orderenumanysettingflagsstring
Problem
I want to set flags which are given in string representation in any order. And it is intimidating, because you have to check like 2^3 possible options in my occassion. I was just wondering is there any better way to do that than just simple brute-force. Any optimization and readability improvment would be great. This is my code:
[Flags]
public enum salaryFeatures
{
Children = 1,
Graduate = 2,
Disability = 4
}
class Program
{
public static void Main()
{
string Employee = "10023 Mark Male 6.7 70 30 20 Children Graduate";
salaryFeatures f;
f = GetFeaturesByString(Employee);
}
public static salaryFeatures GetFeaturesByString(string fields)
{
bool children = false;
bool graduate = false;
bool disability = false;
salaryFeatures features = new salaryFeatures();
if (fields.ToLower().Contains("children")) children = true;
if (fields.ToLower().Contains("graduate")) graduate = true;
if (fields.ToLower().Contains("disability")) disability = true;
if (children && graduate && disability)
{
return features = salaryFeatures.Children | salaryFeatures.Disability | salaryFeatures.Graduate;
}
if (children && graduate)
{
return features = salaryFeatures.Children | salaryFeatures.Graduate;
}
if (children && disability)
{
return features = salaryFeatures.Children | salaryFeatures.Disability;
}
if (children)
{
return features = salaryFeatures.Children;
}
if (graduate && disability)
{
return features = salaryFeatures.Graduate | salaryFeatures.Disability;
}
if (graduate)
{
return features = salaryFeatures.Graduate;
}
if (disability)
{
return features = salaryFeatures.Disability;
}
return features;
}
}Solution
Here is my take on your code
First of the definition of your Enumeration is not complete. You need to define a None value for it
Use None as the name of the flag enumerated constant whose value is
zero. You cannot use the None enumerated constant in a bitwise AND
operation to test for a flag because the result is always zero.
However, you can perform a logical, not a bitwise, comparison between
the numeric value and the None enumerated constant to determine
whether any bits in the numeric value are set.
See also the Guidelines when defining a Flags enum. I also change the naming of the enum to PascalCase (
After that I have improved your method
[Flags]
public enum SalaryFeatures
{
None= 0,
Children = 1,
Graduate = 2,
Disability = 4
}
class Program
{
public static void Main()
{
string Employee = "10023 Mark Male 6.7 70 30 20 Children Graduate";
SalaryFeatures f;
f = GetFeaturesByString(Employee);
// f.Dump(); //LinqPad only
}
public static SalaryFeatures GetFeaturesByString(string fields)
{
SalaryFeatures features = SalaryFeatures.None;
if (fields.IndexOf("children", StringComparison.OrdinalIgnoreCase) >= 0) features |= SalaryFeatures.Children;
if (fields.IndexOf("graduate", StringComparison.OrdinalIgnoreCase) >= 0) features |= SalaryFeatures.Graduate;
if (fields.IndexOf("disability", StringComparison.OrdinalIgnoreCase) >= 0) features |= SalaryFeatures.Disability;
return features;
}
}First of the definition of your Enumeration is not complete. You need to define a None value for it
Use None as the name of the flag enumerated constant whose value is
zero. You cannot use the None enumerated constant in a bitwise AND
operation to test for a flag because the result is always zero.
However, you can perform a logical, not a bitwise, comparison between
the numeric value and the None enumerated constant to determine
whether any bits in the numeric value are set.
See also the Guidelines when defining a Flags enum. I also change the naming of the enum to PascalCase (
SalaryFeatures).After that I have improved your method
GetFeaturesByString to use bitwise OR to combine the values depending on the values that are found in your string. I also use the method IndexOf(string, StringComparison) to check if the search string exists in the source string, instead of using ToLower() and Contains().Code Snippets
[Flags]
public enum SalaryFeatures
{
None= 0,
Children = 1,
Graduate = 2,
Disability = 4
}
class Program
{
public static void Main()
{
string Employee = "10023 Mark Male 6.7 70 30 20 Children Graduate";
SalaryFeatures f;
f = GetFeaturesByString(Employee);
// f.Dump(); //LinqPad only
}
public static SalaryFeatures GetFeaturesByString(string fields)
{
SalaryFeatures features = SalaryFeatures.None;
if (fields.IndexOf("children", StringComparison.OrdinalIgnoreCase) >= 0) features |= SalaryFeatures.Children;
if (fields.IndexOf("graduate", StringComparison.OrdinalIgnoreCase) >= 0) features |= SalaryFeatures.Graduate;
if (fields.IndexOf("disability", StringComparison.OrdinalIgnoreCase) >= 0) features |= SalaryFeatures.Disability;
return features;
}
}Context
StackExchange Code Review Q#144738, answer score: 3
Revisions (0)
No revisions yet.