Подтвердить что ты не робот

Невозможно неявно преобразовать тип 'Int' в 'T'

Я могу позвонить Get<int>(Stat); или Get<string>(Name);

Но при компиляции я получаю:

Невозможно неявно преобразовать тип 'int' в 'T'

и то же самое для string.

public T Get<T>(Stats type) where T : IConvertible
{
    if (typeof(T) == typeof(int))
    {
        int t = Convert.ToInt16(PlayerStats[type]);
        return t;
    }
    if (typeof(T) == typeof(string))
    {
        string t = PlayerStats[type].ToString();
        return t;
    }
}
4b9b3361

Ответ 1

Каждый раз, когда вы включаете тип в общий , вы почти наверняка делаете что-то неправильно. Дженерики должны быть общими; они должны работать одинаково полностью независимо от типа.

Если T может быть только int или string, тогда вообще не пишите свой код таким образом. Напишите два метода, один из которых возвращает int и тот, который возвращает строку.

Ответ 2

Вы можете использовать Convert.ChangeType() вместо своего настраиваемого кода:

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

Ответ 3

public T Get<T>(Stats type ) where T : IConvertible
{
    if (typeof(T) == typeof(int))
    {
        int t = Convert.ToInt16(PlayerStats[type]);
        return (T)t;
    }
    if (typeof(T) == typeof(string))
    {
        string t = PlayerStats[type].ToString();
        return (T)t;
    }
}

Ответ 4

ChangeType, вероятно, ваш лучший вариант. Мое решение аналогично решению, предоставленному BrokenGlass, с логикой логики try.

static void Main(string[] args)
{
    object number = "1";
    bool hasConverted;
    var convertedValue = DoConvert<int>(number, out hasConverted);

    Console.WriteLine(hasConverted);
    Console.WriteLine(convertedValue);
}

public static TConvertType DoConvert<TConvertType>(object convertValue, out bool hasConverted)
{
    hasConverted = false;
    var converted = default(TConvertType);
    try
    {
        converted = (TConvertType) 
            Convert.ChangeType(convertValue, typeof(TConvertType));
        hasConverted = true;
    }
    catch (InvalidCastException)
    {
    }
    catch (ArgumentNullException)
    {
    }
    catch (FormatException)
    {
    }
    catch (OverflowException)
    {
    }

    return converted;
}

Ответ 5

Попробуйте следующее:

public T Get<T>(Stats type ) where T : IConvertible
{
    if (typeof(T) == typeof(int))
    {
        return (T)(object)Convert.ToInt16(PlayerStats[type]);

    }
    if (typeof(T) == typeof(string))
    {

        return (T)(object)PlayerStats[type];
    }
}

Ответ 6

Рассмотрение логики @BrokenGlass (Convert.ChangeType) не поддерживает тип GUID.

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

Ошибка. Недопустимый перенос из "System.String" в "System.Guid".

Вместо этого используйте следующую логику, используя TypeDescriptor.GetConverter, добавив пространство имен System.ComponentModel.

public T Get<T>(Stats type) where T : IConvertible
{
    (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type])
}

Прочитайте это.

Ответ 8

На самом деле, вы можете просто преобразовать его в object а затем в T

T var = (T)(object)42;

Пример для bool:

public class Program
{
    public static T Foo<T>()
    {
        if(typeof(T) == typeof(bool)) {
            return (T)(object)true;
        }

        return default(T);
    }

    public static void Main()
    {
        bool boolValue = Foo<bool>(); // == true
        string stringValue = Foo<string>(); // == null
    }
}

Иногда такое поведение желательно. Например, при реализации или переопределении универсального метода из базового класса или интерфейса, и вы хотите добавить несколько различных функций, основанных на типе T

Ответ 9

Вы можете просто разыграть как ниже,

public T Get<T>(Stats type) where T : IConvertible
{
  if (typeof(T) == typeof(int))
  {
    int t = Convert.ToInt16(PlayerStats[type]);
    return t as T;
  }
 if (typeof(T) == typeof(string))
 {
    string t = PlayerStats[type].ToString();
    return t as T;
 }
}