无法将类型'Int'隐式转换为'T'

时间:2011-11-17 17:16:10

标签: c# generics

我可以致电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;
    }
}

9 个答案:

答案 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;
 }
}