Тип возврата универсального метода - PullRequest
11 голосов
/ 21 февраля 2011

У меня есть универсальный метод, который должен вернуть объект универсального типа.Некоторый код:

public static T Foo<T>(string value)
{
    if (typeof(T) == typeof(String))
        return value;

    if (typeof(T) == typeof(int))
        return Int32.Parse(value);

    // Do more stuff
}

Я вижу, что компилятор может жаловаться на это ( "Невозможно преобразовать тип 'String' в 'T'" ), даже если код не долженвызывать любые логические ошибки во время выполнения.Есть ли способ достичь того, что я ищу?Кастинг не помогает ...

1 Ответ

19 голосов
/ 21 февраля 2011

Ну, вы можете сделать это:

public static T Foo<T>(string value)
{
    if (typeof(T) == typeof(String))
        return (T) (object) value;

    if (typeof(T) == typeof(int))
        return (T) (object) Int32.Parse(value);

    ...
}

Это будет включать в себя бокс для типов значений, но это будет работать.

Вы уверены, что это лучше?сделано как единый метод, а не (скажем) универсальный интерфейс, который может быть реализован различными конвертерами?

В качестве альтернативы, вы можете захотеть Dictionary<Type, Delegate>, например:

Dictionary<Type, Delegate> converters = new Dictionary<Type, Delegate>
{
    { typeof(string), new Func<string, string>(x => x) }
    { typeof(int), new Func<string, int>(x => int.Parse(x)) },
}

тогда вы будете использовать это так:

public static T Foo<T>(string value)
{
    Delegate converter;
    if (converters.TryGetValue(typeof(T), out converter))
    {
        // We know the delegate will really be of the right type
        var strongConverter = (Func<string, T>) converter;
        return strongConverter(value);
    }
    // Oops... no such converter. Throw exception or whatever
}
...