Невозможно неявно преобразовать тип '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;
}
}
Ответы
Ответ 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])
}
Прочитайте это.
Ответ 7
Похоже, вам нужен TypeConverter
, см. эту запись в блоге.
Ответ 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;
}
}