I created these little utility methods to build fluent C# dictionaries. The value declarations shall be quick to write and easy to comprehend when somebody views the code. Usage conditions are as follows:
- many keys point to the same values
- group keys pointing to one value. Declare value only once for better visual comprehension.
- only relatively few values (usually 10 to 20, rarely up to 100)
- main application purpose: replace switch-case blocks in legacy code
The keys/values can also be added otherwise, such as from all constants or Resource content, and can be of any type useful to be declared in code.
In addition, I created an extension convenience method: simply .ToDictionary(), instead of constructor lambdas kv => kv.Key, kv => kv.Value
Is this good, or are there any problems or better ideas? What about performance when used frequently, compared to switch-case?
Usage/test:
class Program
{
public const string RoadVehicles = "RoadVehicles";
public const string RailVehicles = "RailVehicles";
public const string Watercraft = "Watercraft";
public const string Aircraft = "Aircraft";
public static readonly IReadOnlyDictionary<string, string> GroupsForVehicles =
FluentDictionaries.KeysToValue(
RoadVehicles, "Car", "Truck", "Tractor", "Motorcycle")
.KeysToValue(
RailVehicles, "Locomotive", "Railcar", "Powercar", "Handcar")
.KeysToValue(
Watercraft, "Ship", "Sailboat", "Rowboat", "Submarine")
.KeysToValue(
Aircraft, "Jetplane", "Propellerplane", "Helicopter", "Glider", "Balloon")
.ToDictionary();
static void Main(string[] args)
{
foreach (var key in GroupsForVehicles.Keys.OrderBy(key => key))
{
Console.WriteLine(key + ": " + GroupsForVehicles[key]);
}
Console.ReadLine();
}
}
The fluent methods:
public static class FluentDictionaries
{
public static IEnumerable<KeyValuePair<TKey, TValue>> KeysToValue<TKey, TValue>(TValue value, params TKey[] keys)
{
return keys.Select(key =>
new KeyValuePair<TKey, TValue>(key, value));
}
public static IEnumerable<KeyValuePair<TKey, TValue>> KeysToValue<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> previous, TValue value, params TKey[] keys)
{
return previous.Concat(keys.Select(key =>
new KeyValuePair<TKey, TValue>(key, value)));
}
public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs)
{
return keyValuePairs.ToDictionary(kv => kv.Key, kv => kv.Value);
}
}
Test output of the program above:
Balloon: Aircraft
Car: RoadVehicles
Glider: Aircraft
Handcar: RailVehicles
Helicopter: Aircraft
Jetplane: Aircraft
Locomotive: RailVehicles
Motorcycle: RoadVehicles
Powercar: RailVehicles
Propellerplane: Aircraft
Railcar: RailVehicles
Rowboat: Watercraft
Sailboat: Watercraft
Ship: Watercraft
Submarine: Watercraft
Tractor: RoadVehicles
Truck: RoadVehicles
Dictionarycannot do? \$\endgroup\$