Comment décider qu’un type est une structure personnalisée?

Pour un Type , il existe une propriété IsClass en C #, mais comment décider qu’un Type est une structure?

Bien que IsValueType soit une condition nécessaire, elle ne suffit évidemment pas. Pour un int c’est aussi un type de valeur.

Quelqu’un suggère le code suivant:

 bool IsStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive; 

Mais je ne suis pas sûr que ce soit une méthode précise. La formule devrait faire la différence entre struct et d’autres types tels que DateTime , int et array s.

Comme des amis l’ont souligné, je parle ici d’une structure définie par l’utilisateur et non de types prédéfinis , tels que DateTime .

Techniquement, un int est aussi une structure. IsPrimitive vérifie simplement si le type est l’un des types primitifs que le CLR gère un peu différemment. Vous devriez être d’ IsValueType && !IsEnum && !IsPrimitive avec la suggestion IsValueType && !IsEnum && !IsPrimitive .

Si vous souhaitez uniquement des structures personnalisées (c’est-à-dire non fournies par la BCL), vous aurez peut-être de la chance en excluant les types avec un nom complet commençant par "System." , ou n’incluez que ceux qui vous intéressent en filtrant par assemblage ou espace de noms, ou utilisez un atsortingbut personnalisé.

Devrait être au moins

 bool isStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive && type != typeof(decimal); 

http://msdn.microsoft.com/en-us/library/bfft1t3c.aspx dit: IsValueType est vrai si le type est {bool, byte, char, décimal, double, enum, float, int, long, sbyte, court , struct, uint, ulong, ushort}.

http://msdn.microsoft.com/en-us/library/system.type.isprimitive%28v=vs.110%29.aspx dit: IsPrimitive est vrai si le type est {Boolean, Byte, SByte, Int16, UInt16 , Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double et Single}.

Pour IsStruct, vous pouvez utiliser une méthode comme celle-ci:

 public static bool IsStruct(this Type type) { return type.IsValueType && !type.IsPrimitive && !type.IsEnum && type != typeof(decimal); } 

Vous allez avoir un moment difficile avec cela. Le framework de base ne sait pas quels sont tous les types prédéfinis dans les autres parties du framework. Par exemple, il est déraisonnable de s’attendre à ce que le cadre principal connaisse System.Drawing.Point .

OregonGhost a probablement la meilleure réponse : obtenez les informations sur le type et vérifiez la propriété FullName pour voir si elle commence par "System." . Mais vous devez également vérifier "Microsoft." et "FSharp" , et éventuellement d’autres. Cliquez simplement sur “Ajouter une référence” dans Visual Studio et voyez quels noms apparaissent.

Et vous risqueriez alors de bloquer trop. Microsoft dissortingbue certains assemblys via des packages NuGet, et les types de ces assemblys ont souvent un nom commençant par "System." ou "Microsoft." Considérez-vous ces types “intégrés” même s’ils ne sont pas dissortingbués avec Framework?

Cela a fonctionné pour moi! X.PropertyType.IsSecurityTransparent && x.PropertyType.IsClass

La solution n’est pas parfaite, mais vous pouvez toujours envisager de restreindre la recherche en fonction des types connus dans les ensembles que vous souhaitez rechercher:

 System.Reflection.Assembly.GetAssembly(tyepof(OneOfMyTypes)) .GetExportedTypes() .Where(t => t.IsValueType); 

Cela aide à éliminer les faux positifs (plus sûr?), Mais c’est moins portable.