Je souhaite convertir une chaîne en un type générique tel que int
ou date
ou long
en fonction du type de retour générique.
Fondamentalement, une fonction telle que Parse<T>(String)
qui renvoie un élément de type T
.
Par exemple, si un int est passé, la fonction doit faire int.parse
en interne.
Selon votre exemple, vous pourriez faire:
int i = (int)Convert.ChangeType("123", typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("2009/12/12", typeof(DateTime));
Pour satisfaire à votre exigence de "type de retour générique", vous pouvez écrire votre propre méthode d'extension:
public static T ChangeType<T>(this object obj)
{
return (T)Convert.ChangeType(obj, typeof(T));
}
Cela vous permettra de faire:
int i = "123".ChangeType<int>();
On dirait bien que je suis trop tard pour répondre à ce sujet. Mais voici ma mise en œuvre:
En gros, j'ai créé une méthode Extention pour la classe Object. Il gère tous les types, à savoir nullable, classes et struct.
public static T ConvertTo<T>(this object value)
{
T returnValue;
if (value is T variable)
returnValue = variable;
else
try
{
//Handling Nullable types i.e, int?, double?, bool? .. etc
if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
returnValue = (T) conv.ConvertFrom(value);
}
else
{
returnValue = (T) Convert.ChangeType(value, typeof(T));
}
}
catch (Exception)
{
returnValue = default(T);
}
return returnValue;
}
System.Convert.ChangeType
ne convertit en aucun type. Pensez à ce qui suit:
Ces conversions sont possibles avec cette implémentation de ChangeType .
version plus propre de réponse de Pranay
public static T ConvertTo<T>(this object value)
{
if (value is T variable) return variable;
try
{
//Handling Nullable types i.e, int?, double?, bool? .. etc
if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
}
return (T)Convert.ChangeType(value, typeof(T));
}
catch (Exception)
{
return default(T);
}
}
Il existe plusieurs conventions dans le .NET pour convertir des objets d’un type à un autre.
Mais ces méthodes sont beaucoup plus lentes que votre T.Parse(string)
typique, provoquent la boxe et impliquent de nombreuses allocations à chaque fois que vous souhaitez convertir une seule valeur.
Pour ValueString , j'ai choisi de rechercher une méthode d'analyse statique appropriée du type en utilisant la réflexion, de construire une expression lambda pour l'appeler et de mettre en cache le délégué compilé pour une utilisation ultérieure (voir cette réponse pour un exemple).
Cela renvoie également aux méthodes que j'ai mentionnées ci-dessus si le type ne dispose pas d'une méthode d'analyse appropriée (voir la section performance dans le fichier Lisez-moi).
var v = new ValueString("15"); // struct
var i = v.As<int>(); // Calls int.Parse.