Динамическое отображение функций - PullRequest
4 голосов
/ 23 декабря 2011

Я хотел бы определить следующие две функции:

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

T Call<T>(string value);

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

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

Ответы [ 2 ]

5 голосов
/ 23 декабря 2011

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

(ссылка MSDN здесь использует 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 голосов
/ 23 декабря 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...