tipo puede objeto implícitamente implicitamente error cs0029 convertir c# generics

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