是否可以创建一个返回两种可能类型之一的方法?

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要么stringHashSet<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)

更干净!

mil*_*ose 8

要解决缺少通用接口的问题,可以使用一组委托类型参数创建一个ad-hoc:

void MethodThatDoesAllTheLogic(Action<string, string> addFunc)
{
    // ...
    addFunc(key, value);
    // ...
}

public Dictionary<...> PopulateDictionary()
{
    // ...
    MethodThatDoesAllTheLogic(result.Add);
}
Run Code Online (Sandbox Code Playgroud)

(根据需要添加更多参数.)