I have 2 data structures: Dictionary<string, string> and Multimap<string, string> . Multimap is just a dictionary under the hood. I took the code from this question . Here's the class definition:
public class Multimap<TKey, TValue> : Dictionary<TKey, HashSet<TValue>> { ... }
Both data structures have a .Add(TKey key, TValue value) method.
I have a class that is responsible for populating these cards from specific files. I currently have the following two methods:
public Dictionary<string, string> PopulateDictionary(...) { Dictionary<string, string> returnDictionary = new Dictionary<string, string>(); ... foreach (...) { ... returnDictionary.Add(key, value); } return returnDictionary; } public Multimap<string, string> PopulateMultimap(...) { Multimap<string, string> returnMultimap = new Multimap<string, string>(); ... foreach (...) { ... returnMultimap.Add(key, value); } return returnMultimap; }
As you can see, they are exactly the same as about 25 lines, and the only difference is their return type. What I'm going to do is condense this into one method. My first attempt was to have a method
public Dictionary<string, object> PopulateGenericDictionary(...) { ... }
Where object was either string or HashSet<string> . But I was not lucky with Dictionary<string, object> to Multimap<string, string> .
Extracting logic from methods is an option, but it is not very convenient. Due to foreach loops, there is always some kind of logic inside two methods. As a result, you get methods that are half as much, but there are two more identical methods that really do not solve the problem.
This would be my ideal method structure:
public Dictionary<string, string> PopulateDictionary(...) { return MethodThatDoesAllTheLogic(...); } public Multimap<string, string> PopulateMultimap(...) { return MethodThatDoesAllTheLogic(...); } public ??? MethodThatDoesAllTheLogic(...) { ... }
I do casting and generics, but I just can't get it to work. Any ideas?
Edit
I used a millimose solution. Here is my code now:
public Dictionary<string, string> GenerateDictionary(...) { Dictionary<string, string> returnMap = new Dictionary<string, string>(); PopulateDictionary(returnMap.Add, ...); return returnMap; } public Multimap<string, string> GenerateMultimap(...) { Multimap<string, string> returnMap = new Multimap<string, string>(); PopulateDictionary(returnMap.Add, ...); return returnMap; } private static void PopulateGenericDictionary(Action<string, string> addFunc, ...) { ... foreach (...) { addFunc(key, value); } }
Significantly cleaner!