Call different methods in a generic method based on the type parameter

I have a few methods like this:

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

Now I want to write a generic method which has the following signature:

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

Depending on the type parameter I want to invoke copyAction with the return value of one of the non-generic methods. My first try was

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;
}

But this doesn't even compile. I then tried to wrap my non-generic metods in generic ones like

public string GetValue<string>(string field)
{
    return GetStringValue(field);
}

which obviously doesn't compile either.

Can this be done or do i have to explicitly implement CopyValue for each type?

Jon Skeet
people
quotationmark

You can get it to work with casting, but it's ugly:

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

(etc)

This sort of thing always ends up being fairly ugly, to be honest. One option would be to create a Dictionary<Type, Delegate> like this:

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

Then you can use:

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;
}

people

See more on this question at Stackoverflow