objeto - no se puede convertir implicitamente el tipo string a int c#
No se puede convertir implícitamente el tipo ''Int'' a ''T'' (8)
Puedo llamar a Get<int>(Stat);
o Get<string>(Name);
Pero al compilar, obtengo:
No se puede convertir implícitamente el tipo ''int'' a ''T''
y lo mismo para la 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;
}
}
Cada vez que te encuentras cambiando un tipo en un genérico , casi con seguridad estás haciendo algo mal . Los genéricos deben ser genéricos ; deberían funcionar de forma idéntica y completamente independientes del tipo .
Si T solo puede ser int o cadena, no escriba su código de esta manera en primer lugar. Escriba dos métodos, uno que devuelva un int y otro que devuelva una cadena.
Debería poder usar Convert.ChangeType()
lugar de su código personalizado:
public T Get<T>(Stats type) where T : IConvertible
{
return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}
En realidad, puedes convertirlo a un object
y luego a T
T var = (T)(object)42;
Un ejemplo para 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
}
}
A veces, este comportamiento es deseable. Por ejemplo, al implementar o reemplazar un método genérico de una clase base o interfaz y desea agregar algunas funcionalidades diferentes basadas en el tipo T
Parece que necesitas un TypeConverter
, mira this .
Prueba esto:
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];
}
}
Teniendo en cuenta la lógica @BrokenGlass ( Convert.ChangeType
) no es compatible con el tipo de GUID.
public T Get<T>(Stats type) where T : IConvertible
{
return (T) Convert.ChangeType(PlayerStats[type], typeof(T));
}
Error : conversión inválida de ''System.String'' a ''System.Guid''.
En su lugar, utilice la lógica siguiente utilizando TypeDescriptor.GetConverter
agregando espacio de nombres System.ComponentModel
.
public T Get<T>(Stats type) where T : IConvertible
{
(T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type])
}
Lee this
ChangeType
es probablemente su mejor opción. Mi solución es similar a la proporcionada por BrokenGlass con un poco de lógica de captura de prueba.
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))
{
int t = Convert.ToInt16(PlayerStats[type]);
return (T)t;
}
if (typeof(T) == typeof(string))
{
string t = PlayerStats[type].ToString();
return (T)t;
}
}