web-dev-qa-db-fra.com

Comment déterminer si un type d'objet est un type de système intégré

J'écris un simple List<t> au convertisseur CSV. Mon convertisseur vérifie tous les t dans la liste et saisit toutes les propriétés publiques et les place dans le CSV.

Mon code fonctionne très bien (comme prévu) lorsque vous utiliserez une classe simple avec quelques propriétés.

J'aimerais obtenir le List<t> au convertisseur CSV pour accepter également les types de système tels que String et Integer. Avec ces types de système, je ne veux pas obtenir leurs propriétés publiques (telles que la longueur, les caractères, etc.). Je voudrais donc vérifier si l'objet est de type System. Par type de système, j'entends l'un des types .Net intégrés tels que string, int32, double etc.

En utilisant GetType (), je peux découvrir les éléments suivants:

string myName = "Joe Doe";

bool isPrimitive = myName.GetType().IsPrimitive; // False
bool isSealed = myName.GetType().IsSealed; // True 
// From memory all of the System types are sealed.
bool isValueType = myName.GetType().IsValueType; // False

// LinqPad users: isPrimitive.Dump();isSealed.Dump();isValueType.Dump();

Comment puis-je trouver si la variable myName est un type de système intégré? (en supposant que nous ne connaissons pas sa chaîne)

41
Jeremy

myName.GetType().Namespace
Cela retournera System s'il s'agit d'un type intégré.

43
ItsPete

Voici quelques-unes des nombreuses possibilités:

  • myName.GetType().Namespace == "System"
  • myName.GetType().Namespace.StartsWith("System")
  • myName.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"
55
Gabe

Si vous ne parvenez pas à définir précisément ce qu'est un "type de système intégré", il semble probable que vous ne saurez pas quels types figurent dans les réponses données. Plus probablement, ce que vous voulez faire, c'est simplement avoir une liste des types avec lesquels vous ne voulez pas faire cela. Avoir une méthode "IsSimpleType" qui vérifie simplement différents types.

L'autre chose que vous recherchez peut-être est les types primitifs. Si oui, regardez:

Type.IsPrimitive ( http://msdn.Microsoft.com/en-us/library/system.type.isprimitive.aspx )

Les types primitifs sont Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double et Single.

Cela n'inclut pas la chaîne mais vous pouvez l'ajouter manuellement ...

Voir aussi Comment tester si le type est primitif

10
Chris

Les méthodes basées sur l'espace de noms peuvent potentiellement provoquer des collisions.

Il existe un autre moyen fiable et simple:

static bool IsSystemType(this Type type) => type.Assembly == typeof(object).Assembly;

Ou un peu plus optimal, en mettant en cache l'Assemblée système:

static readonly Assembly SystemAssembly = typeof(object).Assembly;

static bool IsSystemType(this Type type) => type.Assembly == SystemAssembly;
8
Makeman

Je pense que c'est la meilleure possibilité:

private static bool IsBulitinType(Type type)
{
    return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object);
}
6
k3flo

Je construisais quelque chose de manière réfléchie et j'ai constaté que la propriété IsSecurityCritical semblait fonctionner à cette fin; cependant, c'était uniquement parce que le niveau de confiance pour mon assembly n'était pas assez élevé pour inverser ce bit.

Un peu de rire; heureusement, j'ai trouvé cette question et je m'adapterai en conséquence.

Remarque: La propriété IsSecurityCritical n'existe que si .NetFramework> 4

J'irai probablement avec; ce qui suit d'une réponse précédente.

myName.GetType (). Module.ScopeName == "CommonLanguageRuntimeLibrary"

Mais, avec quelques ajustements; comme en faire une méthode d'extension sur Type et utiliser un const pour CommonLanguageRuntimeLibrary

3
dasm80x86

Compte tenu des mises en garde entourant les réponses existantes, je vais suggérer une solution Windows uniquement:

public static class TypeExt {
    public static bool IsBuiltin(this Type aType) => new[] { "/dotnet/shared/Microsoft", "/windows/Microsoft.net" }.Any(p => aType.Assembly.CodeBase.ToLowerInvariant().Contains(p));
}

Vraisemblablement, il existe un chemin similaire sur d'autres systèmes d'exploitation pris en charge.

0
NetMage