J'ai un bloc de code qui sérialise un type dans une balise Html.
Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T
tagBuilder.Attributes.Add("class", t.Name);
foreach (PropertyInfo prop in t.GetProperties())
{
object propValue = prop.GetValue(myObj, null);
string stringValue = propValue != null ? propValue.ToString() : String.Empty;
tagBuilder.Attributes.Add(prop.Name, stringValue);
}
Cela fonctionne très bien, sauf que je veux seulement faire cela pour les types primitifs, comme int
, double
, bool
etc, et d' autres types qui ne sont pas primitifs , mais peut être sérialisé facilement comme string
. Je veux qu'il ignore tout le reste, comme les listes et autres types personnalisés.
Quelqu'un peut-il suggérer comment je fais cela? Ou dois-je spécifier les types que je souhaite autoriser quelque part et activer le type de propriété pour voir s'il est autorisé? C'est un peu brouillon, donc ce serait bien s'il y avait un moyen plus ordonné.
c#
reflection
primitive-types
DaveDev
la source
la source
System.String
n'est pas un type primitif.Réponses:
Vous pouvez utiliser la propriété
Type.IsPrimitive
, mais soyez prudent car il existe certains types que nous pouvons penser comme primitifs, mais ils ne le sont pas, par exempleDecimal
etString
.Edit 1: exemple de code ajouté
Voici un exemple de code:
Edit 2: Comme le commente @SLaks , il y a d'autres types que vous voudrez peut-être aussi traiter comme des primitives. Je pense que vous devrez ajouter ces variations une par une .
Edit 3: IsPrimitive = (Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single), type Anther Primitive-Like à vérifier (t == typeof (DateTime ))
la source
DateTime
- êtreTimeSpan
, etDateTimeOffset
.||
), pas le ou (|
) au niveau du bit .Je viens de trouver cette question en cherchant une solution similaire et j'ai pensé que vous pourriez être intéressé par l'approche suivante utilisant
System.TypeCode
etSystem.Convert
.Il est facile de sérialiser tout type mappé à un
System.TypeCode
autre queSystem.TypeCode.Object
, vous pouvez donc faire:L'avantage de cette approche est que vous n'avez pas à nommer tous les autres types non primitifs acceptables. Vous pouvez également modifier légèrement le code ci-dessus pour gérer tout type qui implémente IConvertible.
la source
Guid
pour mes propres besoins (en tant que primitif dans ma définition).Nous le faisons comme ceci dans notre ORM:
Je sais que l'utilisation
IsValueType
n'est pas la meilleure option (vous pouvez avoir vos propres structures très complexes) mais cela fonctionne dans 99% des cas (et inclut les Nullables).la source
decimal
à cet égard. Mais y a-t-il un type pour lequelIsPrimitive
retournetrue
maisIsValueType
retournefalse
? S'il n'y en a pas, let.IsPrimitive
test n'est pas nécessaire.IsValueType
la valeur true, donc la vérificationIsPrimitive
n'est pas nécessaire. À votre santé!À partir de la réponse @Ronnie Overby et du commentaire @jonathanconway, j'ai écrit cette méthode qui fonctionne pour Nullable et exclut les structures utilisateur.
Avec le TestCase suivant:
la source
Enum
n'est pas prise en charge, testez-la avecenum MyEnum { EnumValue }
et utilisezMyEnum
. @Jonathan utilise égalementtype.IsValueType
. Avec cela, ilsEnums
sont correctement détectés, mais aussiStructs
. Alors faites attention aux primitifs que vous voulez.type.IsValueType
, pourquoi simplement ne pas ajoutertype.IsEnum
?type.IsEnum
est également possible. J'ai suggéré une modification sur votre message :)Voici comment je l'ai fait.
la source
IsAssignableFrom
dans votre test au lieu de contient?Aussi une bonne possibilité:
la source
Type
a une propriété appelée IsPrimitive . Vous devriez utiliser cela à la place.String
niDecimal
les primitifs.En supposant que vous ayez une signature de fonction comme celle-ci:
Vous pouvez ajouter une contrainte générique pour autoriser uniquement les types valeur:
Notez que cela autorise non seulement les types primitifs pour T, mais tout type valeur.
la source
J'avais besoin de sérialiser les types pour les exporter vers XML. Pour ce faire, j'ai parcouru l'objet et opté pour des champs primitifs, enum, de type valeur ou sérialisables. C'était le résultat de ma requête:
J'ai utilisé LINQ pour parcourir les types, puis obtenir leur nom et leur valeur à stocker dans une table de symboles. La clé est dans la clause «où» que j'ai choisie pour la réflexion. J'ai choisi des types primitifs, énumérés, valeur et des types sérialisables. Cela a permis aux chaînes et aux objets DateTime de passer comme prévu.
À votre santé!
la source
C'est ce que j'ai dans ma bibliothèque. Les commentaires sont les bienvenus.
Je vérifie d'abord IsValueType, car il gère la plupart des types, puis String, car c'est le deuxième plus courant. Je ne peux pas penser à une primitive qui n'est pas un type valeur, donc je ne sais pas si cette jambe du si jamais est touchée.
Ensuite, je peux l'utiliser comme ceci:
la source
Je veux juste partager ma solution. C'est peut-être utile à n'importe qui.
la source
IsPrimitiveType(typeof(System.AccessViolationException)) == true
namespace System { class MyNonPrimitiveType { } }
N'oubliez pas de vérifier l'espace de noms NULL, car les objets anonymes n'ont pas d'espace de noms attribué
la source
Voici une autre option viable.
la source