slocumro
slocumro

Reputation: 268

Function with derived type parameter in a dictionary with the Type as the Key

I want to be able to store a function in a dictionary with the Key being the object type. All functions will accept objects derived from the same base class. I want to be able to convert (based on a registered function) a class into a DbCommand. I've listed my code below in the form that seems correct but something is wrong with the syntax, etc. I think I'm missing something really simple... Any help will be greatly appreciated!

private Dictionary<object, Func<TrackingRecord, DbCommand>> conversionFunctions = new Dictionary<object, Func<TrackingRecord, DbCommand>>();


public void RegisterConversionFunction<T>(Func<T, DbCommand> conversionFunction) where T : TrackingRecord
    {
        conversionFunctions.Add(typeof(T), conversionFunction);
    }

public DbCommand GetConverstion<T>(T trackingRecord) where T : TrackingRecord
    {
        DbCommand command = null;

        if (conversionFunctions.ContainsKey(trackingRecord.GetType()))
        {
            Func<T, DbCommand> conversionFunction;
            if (conversionFunctions.TryGetValue(trackingRecord.GetType(), out conversionFunction))
            {
                command = conversionFunction.Invoke(trackingRecord);
            }
        }
        else
        {
            command = DefaultConversion(trackingRecord);
        }
        return command;
    }

Upvotes: 2

Views: 643

Answers (1)

Chris Shain
Chris Shain

Reputation: 51359

The problem with your original solution is that the method signature Func<T, DbCommand> doesn't match the expected value Func<TrackingRecord, DbCommand>. To fix this, because you know that T is constrained to inherit from TrackingRecord, you can create a wrapping function that matches the expected signature (Func<TrackingRecord, DbCommand>) and cast the argument to T.

Try this:

private Dictionary<object, Func<TrackingRecord, DbCommand>> conversionFunctions = new Dictionary<object, Func<TrackingRecord, DbCommand>>();

public void RegisterConversionFunction<T>(Func<T, DbCommand> conversionFunction) where T : TrackingRecord
{
    conversionFunctions.Add(typeof(T), tr => conversionFunction((T)tr));
}

public DbCommand GetConverstion<T>(T trackingRecord) where T : TrackingRecord
{
    DbCommand command = null;
    Func<TrackingRecord, DbCommand> conversionFunction;

    if (conversionFunctions.TryGetValue(typeof(T), out conversionFunction))
        command = conversionFunction.Invoke(trackingRecord);
    else
        command = DefaultConversion(trackingRecord);

    return command;
}

Upvotes: 4

Related Questions