In my .NET Framework app (stuck at C# 7.3),
I use many if
checks against group of constants in so many places (maintained more than 10 years).
Existing:
public static class Constants
{
public const int Source1 = 111;
public const int Source2 = 123;
public const int Source3 = 135;
// many more
public const int Source999 = 1234;
}
// in some place
if(source == Constants.Source1 // belongs to group A
|| source == Constants.Source2 // belongs to group A
|| source == Constants.Source3 // belongs to group A
|| source == Constants.Source4 // belongs to group A & B
|| source == Constants.Source5 // belongs to group A & B
|| source == Constants.Source6) // belongs to group A & B
{ /** do something **/ }
// in other place
if(source == Constants.Source9 // belongs to group C
|| source == Constants.Source10 // belongs to group C
|| source == Constants.Source11) // belongs to group C
{ /** do something **/ }
// combination of groups B, C & D
if(source == Constants.Source4 // belongs to group A & B
|| source == Constants.Source5 // belongs to group A & B
|| source == Constants.Source6 // belongs to group A & B
|| source == Constants.Source7 // belongs to group B
|| source == Constants.Source8 // belongs to group B
|| source == Constants.Source9 // belongs to group C
|| source == Constants.Source10 // belongs to group C
|| source == Constants.Source11 // belongs to group C
|| source == Constants.Source12 // belongs to group D
|| source == Constants.Source13 // belongs to group D
|| source == Constants.Source14 // belongs to group D & E
|| source == Constants.Source15) // belongs to group D & E
{ /** do something **/ }
// groups B, C & D with exception of A & E
if(source == Constants.Source7 // belongs to group B
|| source == Constants.Source8 // belongs to group B
|| source == Constants.Source9 // belongs to group C
|| source == Constants.Source10 // belongs to group C
|| source == Constants.Source11 // belongs to group C
|| source == Constants.Source12 // belongs to group D
|| source == Constants.Source13) // belongs to group D
{ /** do something **/ }
The problem:
Readability and maintainability.
I always change many conditions when introducing new source. After years, the need of grouping them becoming clear.
The change:
Instead of checking against group of constants, it should check against group of groups of constants.
So I start defining the groups:
public static class SourceGroups
{
public static int[] A => new[] {
Constants.Source1,
Constants.Source2,
Constants.Source3,
Constants.Source4,
Constants.Source5,
Constants.Source6
};
public static int[] B => new[] {
Constants.Source4,
Constants.Source5,
Constants.Source6,
Constants.Source7,
Constants.Source8
};
// many more
}
// most usages becomes very simple
if (SourceGroups.A.Contains(source))
{ /** do something **/ }
// as well as combination of groups
if (SourceGroups.B.Contains(source)
|| SourceGroups.C.Contains(source)
|| SourceGroups.D.Contains(source))
{ /** do something **/ }
// combination with exception
foreach(var item in items)
{
var source = item.Source;
// it sacrifice performance here due to preparing the correct list before checking
var eligibleForOperation1 = SourceGroups.B
.Concat(SourceGroups.C)
.Concat(SourceGroups.D)
.Except(SourceGroups.A)
.Except(SourceGroups.E);
if (eligibleForOperation1.Contains(item.Source))
{
// operation 1
}
// and sacrifice performance here
var eligibleForOperation2 = SourceGroups.F
.Concat(SourceGroups.G)
.Except(SourceGroups.H);
if (eligibleForOperation2.Contains(item.Source))
{
// operation 2
}
}
Performance sacrifice in the last case. But, I guess, It's still okay-ish.
I might miss something so I appreciate if you guys have any feedback.
1234
? More background information, please. (var source = item.Source;
... The variablesource
doesn't appear to be used anywhere.) \$\endgroup\$#include <ctype.h>
provides access to a number of very fast "look-up" functions to check the characteristics of up to 256 different binary values (typically ASCII characters). For example only one ofisupper()
andislower()
would be true ifisalpha()
is true. A simple table looked of one element whose address is one byte but whose content is (likely) 16 bits wide for 16 different properties. Can you see a solution to your problem that is analogous to this that doesn't invoke so much code? \$\endgroup\$