Dictionary instead of switch or if statements v2

Dictionary instead of switch or if statements v2

.NETC#dictionarydelegates

In the previous article I talked about how, in my opinion, is possible to improve the code quality by storing keys/values in a dictionary instead of using switch or conditional statements. What if instead we had some business logic to implement in order to retrieve the hit points for each type of Pokemon? Don't worries, dictionaries and the use of pre-defined delegates such as Action and Func do it for us.

I added two more enums to avoid the presence of magic numbers, which would increase the noise in the code base.

csharp
public enum FightingGroundType : int
{
GROUND = 1,
AIR = 2,
WATER = 3
}
public enum HitType : int
{
SUPER_WEAK = 1,
WEAK = 2,
EFFECTIVE = 3,
SUPER_EFFECTIVE = 4
}

Let's imagine that we implement the business logic within a manager who will be in charge of fetching hit points based on the Pokemon and the ground type.

csharp
private static int GetHitPointForWaterType(FightingGroundType groundType)
{
// Do some stuff and return value
return (int)(groundType == FightingGroundType.GROUND ? HitType.WEAK : HitType.SUPER_EFFECTIVE);
}
private static int GetHitPointForElectricType(FightingGroundType groundType)
{
// Do some stuff and return value
return (int)(groundType == FightingGroundType.GROUND ? HitType.WEAK : HitType.EFFECTIVE);
}
private static int GetHitPointForGrassType(FightingGroundType groundType)
{
// Do some stuff and return value
return (int)(groundType == FightingGroundType.AIR ? HitType.SUPER_WEAK : HitType.EFFECTIVE);
}
private static int GetHitPointForNormalType(FightingGroundType groundType)
{
// Do some stuff and return value
return (int)HitType.WEAK;
}
[...]

Now we can compare again the different style of implementations.

If statement

csharp
public int GetHitPoint(PokemonType pokemonType, FightingGroundType groundType)
{
var point = 0;
if (pokemonType == PokemonType.NORMAL)
{
point = GetHitPointForNormalType(groundType);
}
else if (pokemonType == PokemonType.GRASS)
{
point = GetHitPointForGrassType(groundType);
}
else if (pokemonType == PokemonType.ELECTRIC)
{
point = GetHitPointForElectricType(groundType);
}
else if (pokemonType == PokemonType.WATER)
{
point = GetHitPointForWaterType(groundType);
}
[...]
return point;
}

Switch statement

csharp
public int GetHitPoint(PokemonType pokemonType, FightingGroundType groundType)
{
var point = 0;
switch (pokemonType)
{
case PokemonType.NORMAL:
point = GetHitPointForNormalType(groundType);
break;
case PokemonType.GRASS:
point = GetHitPointForGrassType(groundType);
break;
case PokemonType.ELECTRIC:
point = GetHitPointForElectricType(groundType);
break;
case PokemonType.WATER:
point = GetHitPointForWaterType(groundType);
break;
[...]
}
return point;
}

Dictionary structure

So, I consider to create a mapping between the available Pokemon type and functions, changing the switch-block or if-else into a dictionary of delegates. The key is the type of the switch statement or conditional if-else statement; the value can be an Action (if functions are void) or Func (if functions return values); in this case I use Func to provide some input parameters and return a value

csharp
private readonly Dictionary<PokemonType, Func<FightingGroundType, int>> _basePointMapDelegates = new Dictionary<PokemonType, Func<FightingGroundType, int>>
{
{ PokemonType.NORMAL, GetHitPointForNormalType },
{ PokemonType.GRASS, GetHitPointForGrassType },
{ PokemonType.ELECTRIC, GetHitPointForElectricType },
{ PokemonType.WATER, GetHitPointForWaterType },
[...]
};
public int GetHitPoint(PokemonType pokemonType, FightingGroundType groundType)
{
return _basePointMapDelegates.ContainsKey(pokemonType) ? _basePointMapDelegates[pokemonType].Invoke(groundType) : 0;
}

Conclusion

The general idea is to reduce the use of switch/if statements to control the flow; I use them often but, however, there are some circumstances where things could be done better using a dictionary or any other suitable collection to achieve the goal.

Github repo: https://github.com/apulito/dictionary-instead-statements-v2

Have a nice day!

Alberto