我可以致电Get<int>(Stat);
或Get<string>(Name);
但是在编译时我得到了:
无法隐式转换类型&#39; int&#39;到了&#39;
与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;
}
}
答案 0 :(得分:118)
您应该只能使用Convert.ChangeType()
而不是自定义代码:
public T Get<T>(Stats type) where T : IConvertible
{
return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}
答案 1 :(得分:118)
每当你发现自己在通用中打开类型时,你几乎肯定会做错了。泛型应该是泛型;它们的操作应完全相同完全独立于类型。
如果T只能是int或string,那么首先不要以这种方式编写代码。 编写两个方法,一个返回一个int,另一个返回一个字符串。
答案 2 :(得分:9)
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;
}
}
答案 3 :(得分:8)
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;
}
答案 4 :(得分:6)
试试这个:
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];
}
}
答案 5 :(得分:4)
考虑@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])
}
阅读this。
答案 6 :(得分:3)
看起来您需要TypeConverter
,请参阅this blog entry。
答案 7 :(得分:3)
实际上,您只需将其转换为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
类型添加一些不同的功能。
答案 8 :(得分:0)
您可以像下面这样简单地投射
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;
}
}