不能隐式地将'Int'类型转换为'T'

时间:2021-10-02 16:34:53

I can call Get<int>(Stat); or Get<string>(Name);

我可以叫< int >(统计);或者 <字符串> (名称);

But when compiling I get:

但在编译时,我得到:

Cannot implicitly convert type 'int' to 'T'

不能隐式地将'int'类型转换为'T'

and the same thing for 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 个解决方案

#1


102  

Any time you find yourself switching on a type in a generic you are almost certainly doing something wrong. Generics should be generic; they should operate identically completely independent of the type.

任何时候你发现自己在转换一个泛型类型时,你几乎肯定做错了什么。仿制药应该通用;它们的操作应该完全独立于类型。

If T can only be int or string then don't write your code this way at all in the first place. Write two methods, one that returns an int and one that returns a string.

如果T只能是int或string,那么首先不要这样写代码。写两种方法,一种返回整数,另一种返回字符串。

#2


99  

You should be able to just use Convert.ChangeType() instead of your custom code:

您应该能够使用Convert.ChangeType()而不是自定义代码:

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

#3


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

#4


6  

ChangeType is probably your best option. My solution is similar to the one provided by BrokenGlass with a bit of try catch logic.

变更类型可能是你最好的选择。我的解决方案与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;
}

#5


6  

Try this:

试试这个:

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


4  

Considering @BrokenGlass logic (Convert.ChangeType) does not support for GUID type.

考虑到@BrokenGlass逻辑(Convert.ChangeType)不支持GUID类型。

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

Error: Invalid cast from 'System.String' to 'System.Guid'.

错误:无效的系统转换。字符串”到“System.Guid”。

Instead, use below logic using TypeDescriptor.GetConverter by adding System.ComponentModel namespace.

相反,使用类型描述符来使用下面的逻辑。GetConverter通过添加系统。ComponentModel名称空间。

public T Get<T>(Stats type) where T : IConvertible
{
    (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type])
}

Read this.

读这篇文章。

#7


3  

It looks like you need a TypeConverter, see this blog entry.

看起来您需要一个TypeConverter,看看这个博客条目。

#8


1  

Actually, you can just convert it to object and then to T.

实际上,你可以把它转换成对象,然后再转换成T。

T var = (T)(object)42;

T var =(T)(对象)42;

An example for 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
    }
}

Sometimes, this behavior is desirable. For instance, when implementing or overriding a generic method from a base class or interface and you want to add some different functionalities based on the T type.

有时,这种行为是可取的。例如,当从基类或接口实现或覆盖泛型方法时,您希望基于T类型添加一些不同的功能。

#1


102  

Any time you find yourself switching on a type in a generic you are almost certainly doing something wrong. Generics should be generic; they should operate identically completely independent of the type.

任何时候你发现自己在转换一个泛型类型时,你几乎肯定做错了什么。仿制药应该通用;它们的操作应该完全独立于类型。

If T can only be int or string then don't write your code this way at all in the first place. Write two methods, one that returns an int and one that returns a string.

如果T只能是int或string,那么首先不要这样写代码。写两种方法,一种返回整数,另一种返回字符串。

#2


99  

You should be able to just use Convert.ChangeType() instead of your custom code:

您应该能够使用Convert.ChangeType()而不是自定义代码:

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

#3


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

#4


6  

ChangeType is probably your best option. My solution is similar to the one provided by BrokenGlass with a bit of try catch logic.

变更类型可能是你最好的选择。我的解决方案与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;
}

#5


6  

Try this:

试试这个:

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


4  

Considering @BrokenGlass logic (Convert.ChangeType) does not support for GUID type.

考虑到@BrokenGlass逻辑(Convert.ChangeType)不支持GUID类型。

public T Get<T>(Stats type) where T : IConvertible
{
    return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}

Error: Invalid cast from 'System.String' to 'System.Guid'.

错误:无效的系统转换。字符串”到“System.Guid”。

Instead, use below logic using TypeDescriptor.GetConverter by adding System.ComponentModel namespace.

相反,使用类型描述符来使用下面的逻辑。GetConverter通过添加系统。ComponentModel名称空间。

public T Get<T>(Stats type) where T : IConvertible
{
    (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type])
}

Read this.

读这篇文章。

#7


3  

It looks like you need a TypeConverter, see this blog entry.

看起来您需要一个TypeConverter,看看这个博客条目。

#8


1  

Actually, you can just convert it to object and then to T.

实际上,你可以把它转换成对象,然后再转换成T。

T var = (T)(object)42;

T var =(T)(对象)42;

An example for 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
    }
}

Sometimes, this behavior is desirable. For instance, when implementing or overriding a generic method from a base class or interface and you want to add some different functionalities based on the T type.

有时,这种行为是可取的。例如,当从基类或接口实现或覆盖泛型方法时,您希望基于T类型添加一些不同的功能。