Comment savoir si un type est un type «simple»? c’est à dire détient une valeur unique

typeof(ssortingng).IsPrimitive == false typeof(int).IsPrimitive == true typeof(MyClass).IsClass == true typeof(ssortingng).IsClass == true typeof(ssortingng).IsByRef == false typeof(MyClass).IsByRef == true // correction: should be false (see comments below) 

J’ai une méthode qui instancie une nouvelle instance de T et, si c’est une classe “complexe”, remplit ses propriétés à partir d’un ensemble de valeurs de données source.

(a) Si T est un type simple (par exemple une chaîne ou un int ou autre chose similaire), une conversion rapide des données source en T doit être effectuée.

(b) Si T est une classe (mais pas quelque chose de simple comme une chaîne), alors je vais utiliser Activator.CreateInstance et faire un peu de reflection pour remplir les champs.

Existe-t-il un moyen rapide et simple de savoir si je devrais utiliser la méthode (a) ou la méthode (b)? Cette logique sera utilisée dans une méthode générique avec T comme argument de type.

Ssortingng est probablement un cas particulier.

Je pense que je ferais …..

 bool IsSimple(Type type) { return type.IsPrimitive || type.Equals(typeof(ssortingng)); } 

Modifier:

Parfois, vous devez couvrir d’autres cas, tels que les énumérations et les décimales. Les énumérations sont un type particulier de type en C #. Les décimales sont des structures comme les autres. Le problème avec les structures est qu’elles peuvent être complexes, qu’elles peuvent être des types définis par l’utilisateur, elles peuvent être juste un nombre. Donc, vous n’avez aucune autre chance que de savoir les différencier.

 bool IsSimple(Type type) { return type.IsPrimitive || type.IsEnum || type.Equals(typeof(ssortingng)) || type.Equals(typeof(decimal)); } 

La gestion des contreparties nullables est également un peu délicate. La valeur nullable elle-même est une structure.

 bool IsSimple(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { // nullable type, check if the nested type is simple. return IsSimple(type.GetGenericArguments()[0]); } return type.IsPrimitive || type.IsEnum || type.Equals(typeof(string)) || type.Equals(typeof(decimal)); } 

Tester:

 Assert.IsTrue(IsSimple(typeof(ssortingng))); Assert.IsTrue(IsSimple(typeof(int))); Assert.IsTrue(IsSimple(typeof(decimal))); Assert.IsTrue(IsSimple(typeof(float))); Assert.IsTrue(IsSimple(typeof(SsortingngComparison))); // enum Assert.IsTrue(IsSimple(typeof(int?))); Assert.IsTrue(IsSimple(typeof(decimal?))); Assert.IsTrue(IsSimple(typeof(SsortingngComparison?))); Assert.IsFalse(IsSimple(typeof(object))); Assert.IsFalse(IsSimple(typeof(Point))); // struct in System.Drawing Assert.IsFalse(IsSimple(typeof(Point?))); Assert.IsFalse(IsSimple(typeof(SsortingngBuilder))); // reference type 

Note à .NET Core

Comme le souligne DucoJ dans sa réponse , certaines des méthodes utilisées ne sont plus disponibles sur la classe Type dans .NET core.

Code fixe (j’espère que cela fonctionne, je ne pouvais pas essayer moi-même. Sinon, veuillez commenter):

 bool IsSimple(Type type) { var typeInfo = type.GetTypeInfo(); if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>)) { // nullable type, check if the nested type is simple. return IsSimple(typeInfo.GetGenericArguments()[0]); } return typeInfo.IsPrimitive || typeInfo.IsEnum || type.Equals(typeof(string)) || type.Equals(typeof(decimal)); } 

En plus de Stefan Steinegger, répondez: dans .NET Core, les .IsPrimitive etc. ne sont plus membres de Type, ils sont maintenant membres de TypeInfo. Alors sa solution deviendra alors:

 bool IsSimple(TypeInfo type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { // nullable type, check if the nested type is simple. return IsSimple((type.GetGenericArguments()[0]).GetTypeInfo()); } return type.IsPrimitive || type.IsEnum || type.Equals(typeof(string)) || type.Equals(typeof(decimal)); } 

Il existe un type plus général que primitif, le ValueType englobe beaucoup plus que les primitifs, tels que les énumérations, les décimales et autres choses telles que ValueType . Vous trouverez ci-dessous une fonction que j’ai écrite pour identifier des types complexes pouvant répondre à vos besoins.

  public static bool IsComplex(Type typeIn) { if (typeIn.IsSubclassOf(typeof(System.ValueType)) || typeIn.Equals(typeof(ssortingng))) //|| typeIn.IsPrimitive return false; else return true; } 

Je suis désolé de ressusciter un ancien sujet de travail, mais étant donné que Google figure toujours en tête des recherches sur le Web, vous souhaitez append une solution plus directe et plus efficace:

 if(System.Type.GetTypeCode(typeof(int)) == TypeCode.Object) { // Do what you will... } 

Ce n’est peut-être pas grave, mais il semble que vous ayez omis quelques cas:

  1. Types complexes qui ont des conversions
  2. Types de valeurs qui n’ont pas de constructeur sans paramètre. Exemple ci-dessous:

Il y en a probablement plus, mais je pense que vous partitionnez le problème de manière trop ressortingctive.

  public class Person { private ssortingng _name; private int _age; public Person(ssortingng name, int age) {_name = name; _age = age;} // Remainder of value implementation } 

Les chaînes ne sont pas des primitives, si je me souviens bien. même s’il existe un mot-clé, une chaîne est un object. Votre appel à IsPrimitive vous dira avec précision si quelque chose est une primitive.