Как использовать делегат C # для вызова разных методов, где у каждого свой параметр out? - PullRequest
4 голосов
/ 24 ноября 2011

Следующий вопрос и ответ касаются использования параметра out в делегате:

Func без параметра

Мне нужно сделать еще один шаг. У меня есть несколько методов преобразования (функций), где я хотел бы использовать делегата. Например, давайте начнем с следующих примеров методов:

private bool ConvertToInt(string s, out int value)
{
    try
    {
        value = Int32.Parse(s);
        return true;
    }
    catch (Exception ex)
    {
        // log error
        value = 0;
    }

    return false;
}


private bool ConvertToBool(string s, out bool value)
{
    try
    {
        value = Convert.ToBoolean(s);
        return true;
    }
    catch (Exception ex)
    {
        // log error
        value = false;
    }

    return false;
}

Затем я объявил следующего делегата:

delegate V ConvertFunc<T, U, V>(T input, out U output);

Я хотел бы сделать что-то вроде этого (псевдокод):

if (do int conversion)
    func = ConvertToInt;
else if (do boolean conversion)
    func = ConvertToBool;
else ...

Компилятор позволяет только явно объявить идентификаторы делегата следующим образом:

ConvertFunc<string, int,  bool> func1 = ConvertToInt;
ConvertFunc<string, bool, bool> func2 = ConvertToBool;

Как я могу объявить единственный идентификатор, которому я могу назначить любой из ряда методов, которые следуют вышеупомянутому образцу (основанный на типе преобразования, которое я хочу выполнить)?

Обновление:

Предполагается, что словарь содержит пары значений строки / объекта:

private Dictionary<string, object> dict = new Dictionary<string, object>();

С такими значениями, как:

this.dict.Add("num", 1);
this.dict.Add("bool", true);

Основываясь на ответе, я смог реализовать своего делегата следующим образом:

public T GetProperty<T>(string key)
{
    ConvertFunc<string, T, bool> func = ConvertToT<T>;
    object val = this.dict[key];
    T result;
    if (func(key, out result))
        return result;
    else
        return default(T);
}

1 Ответ

6 голосов
/ 24 ноября 2011

Я думаю, вы ищете что-то вроде

private bool ConvertToT<T>(string s, out T value)
{
    try
    {
        value = (T)Convert.ChangeType(s, typeof(T));

        return true;
    }
    catch (Exception ex)
    {
        // log error // not sure what you're trying here?
        value = default(T);
    }
    return false;
}
...