Je peux appeler Get<int>(Stat);
ouGet<string>(Name);
Mais lors de la compilation, j'obtiens:
Impossible de convertir implicitement le type 'int' en 'T'
et la même chose pour 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;
}
}
Réponses:
Chaque fois que vous vous trouvez en train d'activer un type dans un générique, vous faites certainement quelque chose de mal . Les génériques doivent être génériques ; ils doivent fonctionner de manière identique complètement indépendamment du type .
Si T ne peut être qu'un entier ou une chaîne, n'écrivez pas du tout votre code de cette façon en premier lieu. Écrivez deux méthodes, une qui renvoie un int et une qui renvoie une chaîne.
la source
int, int?, bool, bool?, string
, et c'était apparemment impossible.Vous devriez pouvoir utiliser simplement à la
Convert.ChangeType()
place de votre code personnalisé:public T Get<T>(Stats type) where T : IConvertible { return (T) Convert.ChangeType(PlayerStats[type], typeof(T)); }
la source
return (T)(object)PlayerStats[type];
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; } }
la source
return (T) t;
car aucune vérification nulle n'est nécessaire.ChangeType
est probablement votre meilleure option. Ma solution est similaire à celle fournie par BrokenGlass avec un peu de logique 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; }
la source
Essaye ça:
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]; } }
la source
En fait, vous pouvez simplement le convertir en
object
, puis enT
.T var = (T)(object)42;
Un exemple pour
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 } }
Parfois, ce comportement est souhaitable. Par exemple, lorsque vous implémentez ou remplacez une méthode générique à partir d'une classe ou d'une interface de base et que vous souhaitez ajouter des fonctionnalités différentes en fonction du
T
type.la source
Considérant que @BrokenGlass logic (
Convert.ChangeType
) ne prend pas en charge le type GUID.public T Get<T>(Stats type) where T : IConvertible { return (T) Convert.ChangeType(PlayerStats[type], typeof(T)); }
Erreur : conversion non valide de «System.String» vers «System.Guid».
Au lieu de cela, utilisez la logique ci-dessous
TypeDescriptor.GetConverter
en ajoutant unSystem.ComponentModel
espace de noms.public T Get<T>(Stats type) where T : IConvertible { (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type]) }
Lisez ceci .
la source
Il semble que vous ayez besoin d'un
TypeConverter
, voir cette entrée de blog .la source
Vous pouvez simplement lancer comme ci-dessous,
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; } }
la source