Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Function Mapping

I would like to define the following two functions:

void Map<T>(Func<T, string> mapper);

T Call<T>(string value);

Map needs to store the function that turns a string into a result of type T so that when the "Call" function is called with a type T and a string the appropriate function can be looked up and called.

I was thinking that map could store the function in a dictionary of type Dictionary<Type, Func<object, string>> and then Call could do the casting to the appropriate type but I'm unable to get that to work. Does anyone know how to achieve this?

like image 317
Mikeb Avatar asked Dec 23 '11 06:12

Mikeb


People also ask

What is meant by mapping function?

[ măp′ĭng ] n. A mathematical formula that relates distances on a gene map to recombination frequencies; its graphic rendering shows that the recombination value of two genes is never greater than 50 percent regardless of how far apart the genes are on a chromosome.

Does C# have a map function?

Introduction to Map in C#There is no built-in Map type in C#. It does, however, include a powerful Dictionary type, which we utilize to map objects. We must define the key type (such as "string") and the value type when using Dictionary. We map a key to a value with Add.


1 Answers

The first type argument of Func is the input, the second the output: Func<in T, out TResult> -- so you need Func<string, T>.

(The MSDN reference here uses Func<string, string> a fair bit which is annoying.)

Also, the dictionary can't use the type argument T as that's different for each element in the dictionary. Rather, use the superclass of Func<T, TResult> which is Delegate.

This should work:

    Dictionary<Type, Delegate> dictionary = new Dictionary<Type, Delegate>();

    public void Map<T>(Func<string, T> mapper)
    {
        dictionary[typeof(T)] = mapper;
    }

    public T Call<T>(string value)
    {
        var func = dictionary[typeof(T)] as Func<string, T>;
        return func.Invoke(value);
    }
like image 77
Jeremy McGee Avatar answered Oct 14 '22 17:10

Jeremy McGee