不能将types'Int'隐式转换为'T'
我可以调用Get<int>(Stat);
或Get<string>(Name);
但编译时我得到:
不能将types'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; } }
任何时候你发现自己在一个通用的types中切换, 你几乎肯定会做错的事情 。 generics应该是通用的 ; 它们应该完全独立于types运行 。
如果T只能是int或者string,那么不要这样写代码。 写两个方法,一个返回一个int,一个返回一个string。
你应该能够使用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 as T; } if (typeof(T) == typeof(string)) { string t = PlayerStats[type].ToString(); return t as T; } }
ChangeType
可能是您最好的select。 我的解决scheme与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; }
考虑@BrokenGlass逻辑( Convert.ChangeType
)不支持GUIDtypes。
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]) }
阅读这个 。
它看起来像你需要一个TypeConverter
,看到这个博客条目 。
尝试这个:
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]; } }