J'ai une classe que je veux utiliser pour stocker des "propriétés" pour une autre classe. Ces propriétés ont simplement un nom et une valeur. Idéalement, ce que j'aimerais, c'est pouvoir ajouter des propriétés typées , de sorte que la "valeur" retournée soit toujours du type que je veux qu'elle soit.
Le type doit toujours être une primitive. Cette classe sous-classe une classe abstraite qui stocke essentiellement le nom et la valeur sous forme de chaîne. L'idée étant que cette sous-classe va ajouter une certaine sécurité de type à la classe de base (ainsi que me sauver sur une conversion).
J'ai donc créé une classe qui est (à peu près) la suivante:
public class TypedProperty<DataType> : Property
{
public DataType TypedValue
{
get { // Having problems here! }
set { base.Value = value.ToString();}
}
}
La question est donc:
Existe-t-il un moyen "générique" de reconvertir une chaîne en une primitive?
Je n'arrive pas à trouver d'interface générique qui relie la conversion à tous les niveaux (quelque chose comme ITryParsable aurait été idéal!).
la source
Réponses:
Je ne sais pas si j'ai bien compris vos intentions, mais voyons si celle-ci aide.
la source
Convert.ChangeType
ne soit pas une solution très universelle et extensible, cela fonctionne pour la plupart des types de base. si quelque chose de mieux est nécessaire, il n'y a aucun problème à envelopper cette méthode dans quelque chose de plus grand comme Tim l'a suggéré ou à utiliser une méthode de conversion différente.La méthode de lubos hasko échoue pour les nullables. La méthode ci-dessous fonctionnera pour nullables. Mais je ne l'ai pas inventé. Je l'ai trouvé via Google: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Crédit à "Tuna Toksoz"
Utilisation d'abord:
La classe est ci-dessous.
la source
tc
(laTypeConverter
) une seule fois.TypeConverter
est lent car il utilise la réflexion pour rechercher le fichierTypeConverterAttribute
. Si vous initialisez un seulTypeConverter
champ privé , vous devriez pouvoir réutiliser lesTypeConverter
nombreuses fois.object
, lève une exception. J'ai pu contourner cela en utilisant `if (typeof (T) .IsPrimitive) {return TConverter.ChangeType <T> (StringValue); } else {object o = (object) StringValue; retourner à; } `en remplacement de l'exemple d'utilisationTConverter.ChangeType<T>(StringValue)
Pour de nombreux types (entier, double, DateTime, etc.), il existe une méthode Parse statique. Vous pouvez l'invoquer en utilisant la réflexion:
la source
TypeDescriptor
est une classe ayant une méthodeGetConvertor
qui accepte unType
objet et vous pouvez ensuite appeler laConvertFrom
méthode pour convertir levalue
pour cet objet spécifié.la source
Vous pouvez éventuellement utiliser une construction telle qu'une classe de traits . De cette façon, vous auriez une classe d'assistance paramétrée qui sait convertir une chaîne en une valeur de son propre type. Ensuite, votre getter pourrait ressembler à ceci:
Maintenant, je dois souligner que mon expérience avec les types paramétrés est limitée au C ++ et à ses modèles, mais j'imagine qu'il existe un moyen de faire la même chose en utilisant des génériques C #.
la source
Vérifiez la statique
Nullable.GetUnderlyingType
. - Si le type sous-jacent est nul, alors le paramètre de modèle ne l'est pasNullable
, et nous pouvons utiliser ce type directement - Si le type sous-jacent n'est pas nul, alors utilisez le type sous-jacent dans la conversion.Semble fonctionner pour moi:
la source
En s'inspirant de la réponse de Bob , ces extensions prennent également en charge la conversion de valeur nulle et toutes les conversions primitives de retour et quatrième.
Exemples
la source
J'utilise la conversion via un objet. C'est un peu plus simple.
la source
J'ai utilisé la réponse lobos et cela fonctionne. Mais j'ai eu un problème avec la conversion des doubles à cause des paramètres de culture. J'ai donc ajouté
la source
Encore une autre variation. Gère les valeurs Nullables, ainsi que les situations où la chaîne est nulle et T ne l' est pas .
la source
Vous pouvez le faire sur une seule ligne comme ci-dessous:
Bon codage;)
la source