Tom*_*Tom 4 c# generics dictionary casting
我有2个数据结构:Dictionary<string, string>
和Multimap<string, string>
.Multimap实际上只是一个字典.我从这个问题中得到了必须的代码.这是类定义:
public class Multimap<TKey, TValue> : Dictionary<TKey, HashSet<TValue>>
{ ... }
Run Code Online (Sandbox Code Playgroud)
两种数据结构都有一种.Add(TKey key, TValue value)
方法.
我有一个类负责从某些文件填充这些映射.我目前有以下两种方法:
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;
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,它们完全相同,都长约25行,唯一的区别是它们的返回类型.我想要做的是将其浓缩为一种方法.我的第一次尝试是采用这种方法
public Dictionary<string, object> PopulateGenericDictionary(...)
{ ... }
Run Code Online (Sandbox Code Playgroud)
凡object
要么string
或HashSet<string>
.但是,我并没有太多的运气,从铸造Dictionary<string, object>
到Multimap<string, string>
.
从方法中提取逻辑是一种选择,但它并不好.由于foreach循环,两种方法中总会有一些逻辑.你最终会得到两倍小的方法,但是仍然有两种相同的方法,这些方法并没有真正解决问题.
这将是我理想的方法结构:
public Dictionary<string, string> PopulateDictionary(...)
{
return MethodThatDoesAllTheLogic(...);
}
public Multimap<string, string> PopulateMultimap(...)
{
return MethodThatDoesAllTheLogic(...);
}
public ??? MethodThatDoesAllTheLogic(...)
{ ... }
Run Code Online (Sandbox Code Playgroud)
我一直在摆弄铸造和仿制品,但我无法让它发挥作用.有任何想法吗?
编辑
我用过millimoose的解决方案.这是我现在的代码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
更干净!
要解决缺少通用接口的问题,可以使用一组委托类型参数创建一个ad-hoc:
void MethodThatDoesAllTheLogic(Action<string, string> addFunc)
{
// ...
addFunc(key, value);
// ...
}
public Dictionary<...> PopulateDictionary()
{
// ...
MethodThatDoesAllTheLogic(result.Add);
}
Run Code Online (Sandbox Code Playgroud)
(根据需要添加更多参数.)