基于类型参数在泛型方法中调用不同的方法

时间:2014-08-20 08:25:48

标签: c# .net generics

我有几个像这样的方法:

public string GetStringValue(string field) { /* ... */ }
public int GetIntValue(string field) { /* ... */ }

现在我想编写一个具有以下签名的泛型方法:

public bool CopyValue<T>(string field, Action<T> copyAction)

取决于我想要使用其中一个非泛型方法的返回值调用copyAction的类型参数。我的第一次尝试是

public bool CopyValue<T>(string field, Action<T> copyAction)
{
    if (typeof(T) == typeof(string))
        copyAction((GetStringValue(field));
    else if (typeof(T) == typof(int))
        copyAction(GetIntValue(field));
    else
        return false;

    return true;
}

但这甚至都没有编译。然后我尝试将非泛型方法包装在像

这样的通用方法中
public string GetValue<string>(string field)
{
    return GetStringValue(field);
}

显然也没有编译。

可以这样做,还是我必须为每种类型明确实施CopyValue

1 个答案:

答案 0 :(得分:4)

你可以使用它进行投射,但这很难看:

if (typeof(T) == typeof(string))
{
    copyAction((T)(object) GetStringValue(field));
}

(等)

说实话,这种事情总是相当丑陋。一种选择是创建一个Dictionary<Type, Delegate>,如下所示:

Dictionary<Type, Delegate> fieldExtractors = new Dictionary<Type, Delegate>
{
    { typeof(string), (Func<string, string>) field => GetStringValue(field) },
    { typeof(int), (Func<string, int>) field => GetIntValue(field) },
};

然后你可以使用:

public bool CopyValue<T>(string field, Action<T> copyAction)
{
    Delegate fieldExtractor;
    if (fieldExtractors.TryGetValue(typeof(T), out fieldExtractor))
    {
        var extractor = (Func<string, T>) fieldExtractor;
        copyAction(extractor(field));
        return true;
    }
    return false;
}