Не удается неявно преобразовать тип ' 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;
}
}
8 ответов:
каждый раз, когда вы обнаружите, что включаете тип в общем вы почти наверняка делаете что-то неправильно. Дженерики должны быть generic; они должны работать одинаково полностью не зависит от типа.
Если T может быть только int или string, то вообще не пишите свой код таким образом. напишите два метода, один из которых возвращает int и один, который возвращает строку.
вы должны быть в состоянии просто использовать
Convert.ChangeType()
вместо пользовательского кода:public T Get<T>(Stats type) where T : IConvertible { return (T) Convert.ChangeType(PlayerStats[type], typeof(T)); }
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; } }
ChangeType
скорее всего ваш лучший вариант. Мое решение похоже на то, которое предоставляет BrokenGlass с небольшим количеством логики try catch.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; }
попробуйте это:
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]; } }
учитывая логику @ BrokenGlass (
Convert.ChangeType
) не поддерживает тип GUID.public T Get<T>(Stats type) where T : IConvertible { return (T) Convert.ChangeType(PlayerStats[type], typeof(T)); }
: недопустимое приведение из ' системы.Строка' до 'системы.Guid'.
вместо этого используйте логику ниже, используя
TypeDescriptor.GetConverter
добавлятьSystem.ComponentModel
пространство имен.public T Get<T>(Stats type) where T : IConvertible { (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type]) }
читать этой.
похоже, вам нужен
TypeConverter
см. запись в блоге.
на самом деле, вы можете просто преобразовать его в
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
тип.