2011-12-23 5 views
4

Я хотел бы определить следующие две функции:Динамическая функция Mapping

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

T Call<T>(string value); 

карты необходимо сохранить функцию, которая превращает строку в результат типа T, так что, когда «Вызов» функция вызывается тип T и строку, соответствующая функция может быть просмотрена и вызвана.

Я думал, что карта может хранить функцию в словаре типа Dictionary<Type, Func<object, string>>, а затем Call может сделать кастинг соответствующего типа, но я не могу заставить это работать. Кто-нибудь знает, как добиться этого?

ответ

5

Первый тип аргумента Func является вход, второй выход: Func<in T, out TResult> - так что вам нужно Func<string, T>.

(Ссылка MSDN here использует Func<string, string> справедливый бит, который раздражает.)

Кроме того, словарь не может использовать аргумент типа T как различно для каждого элемента в словаре. Вместо этого используйте суперкласс Func<T, TResult>, который составляет Delegate.

Это должно работать:

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

Вы можете попытаться сделать что-то вроде этого (там должно быть лучше, но я не могу увидеть его прямо сейчас):

Dictinary<Type, object> _funcDict = ...; 

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

T Call<T>(string value) 
{ 
    var func = (Func<T, string>)_funcDict[typeof(T)] 
    return func(value); 
} 

Что мне не нравится, оказывает значение объекта введите словарь, но я не уверен, как вы можете его избежать.

+0

не работает, он должен быть '' Func . См. Мой ответ. –

Смежные вопросы