Je souhaite convertir une chaîne en un type générique comme int
ou date
ou long
basé sur le type de retour générique.
En gros, une fonction comme Parse<T>(String)
celle-ci renvoie un élément de type T
.
Par exemple, si un int a été passé, la fonction doit le faire en int.parse
interne.
c#
string
parsing
type-conversion
Karim
la source
la source
IConvertable
, ne devriez-vous pas également contraindre leT
, c'estT ChangeType<T>(this object obj) where T : IConvertable
-à- dire ?obj
doit êtreIConvertible
, mais il n'y a aucun moyen de le spécifier au moment de la compilation.Eh bien, on dirait que je suis trop tard pour répondre sur ce fil. Mais voici ma mise en œuvre:
Fondamentalement, j'ai créé une méthode Extention pour la classe Object. Il gère tous les types, c'est-à-dire 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; }
la source
TypeDescriptor
pour les types Nullable etConvert.ChangeType
pour les non Nullables? Cetry
bloc entier peut être réduit à seulementTypeConverter
2 lignes de code et il fonctionnera pour les deux, nullable et non nullable.System.Convert.ChangeType
ne convertit en aucun type. Pensez à ce qui suit:Ces conversions sont possibles avec cette implémentation de ChangeType .
la source
version plus propre de la 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); } }
la source
Il existe quelques conventions dans le .NET pour convertir des objets d'un type à un autre.
Mais ces méthodes sont beaucoup plus lentes que vos méthodes habituelles
T.Parse(string)
, provoquent une boxe et impliquent de nombreuses allocations à chaque fois que vous souhaitez convertir une valeur unique.Pour ValueString , j'ai choisi de trouver une méthode d'analyse statique appropriée du type utilisant la réflexion, de créer une expression lambda en l'appelant et de mettre en cache le délégué compilé pour une utilisation future (voir cette réponse pour un exemple).
Il revient également aux méthodes que j'ai mentionnées ci-dessus si le type n'a pas de méthode d'analyse appropriée (voir la section sur les performances dans le readme).
var v = new ValueString("15"); // struct var i = v.As<int>(); // Calls int.Parse.
la source