8
votes

Comment déterminer si un type .NET est une structure personnalisée?

Comment écrire une méthode simple, qui vérifie si un type de béton est une structure personnalisée (créée avec Public Strart {}; ) ou non.

Vérification Type.isvalueType < / code> ne suffit pas, car il est également fidèle à int , long , etc., etc., et ajouter un chèque à ! isprimitivestype exclurea décimal , DateTime et peut-être d'autres types de valeur. Je sais que la plupart des types de valeur intégrée sont en réalité des "structures", mais je veux seulement vérifier "Structs personnalisés"

Ces questions sont la plupart des mêmes mais sans la réponse dont j'ai besoin:

  • # 1
  • # 2
  • # 3

    EDIT: à partir des réponses mentionnées, le "préfixe" de la vérification du système "était le plus stable (bien que ce soit toujours un piratage). J'ai finalement décidé de créer un attribut que vous devez décorer la structure avec, afin que le cadre le ramasse comme une structure personnalisée. (L'autre choix que je pensais était de créer une interface vide et de laisser la structure implémenter cette interface vide, mais l'attribut Way semble plus élégante)

    Voici mon vérificateur de structure personnalisé original si quelqu'un s'intéresse: < / p> xxx


2 commentaires

Juste hors de curiosité, pourquoi voulez-vous le détecter?


Nibernate fluide + Mappage automatique: définissez toutes les structures de fabrication personnalisées à traiter en tant que composants (objets de valeur); Réglage de tout autre type de valeur pour être un composant (comme DateTime ou décimal) plantera tout le cadre (au moins il fait sous Mono)


5 Réponses :


5
votes

Eh bien, datetétime, décimale, etc. répond à vos besoins. En ce qui concerne le CLR concerné, ce sont des structures personnalisées. Un hack, mais vous pouvez simplement vérifier si l'espace de noms commence par "Système".


3 commentaires

Bien sûr, votre propre espace de noms pourrait commencer par le système ... :) Personne ne ferait cela, non?


Oui, c'est pourquoi j'ai appelé qu'un hack.


@Mattgreer: Great Hack en passant, je ne pouvais pas penser à ça :) merci



8
votes

Il n'y a pas de différence entre une structure définie dans le cadre et une structure définie par vous-même.

Un couple d'idées pourrait être:

  • garder une liste blanche de structs-cadres et exclure ceux-ci;
  • Identifiez l'assemblage (DLL) le type est défini dans et conserver une blancheur d'assemblages-cadre.
  • Identifiez l'espace de noms le type vit et excluez les cadres.

3 commentaires

Dans le contexte du commentaire sur l'utilisation de NHibernate fluide, une liste blanche de structures "bien connues" serait la meilleure approche. La liste est suffisamment courte pour être facilement comprise et risque de ne jamais changer.


D'accord, comme vous y trouvez chacun qui provoque un crash, ajoutez-le à la liste blanche (ou liste noire ou autre que vous l'appelez) et continuez. Le cadre n'a pas trop de structs.


Oui, mais malheureusement, il n'y a pas de liste pour cela. Et si vous manquez quelque chose et utilisez cette structure plus tard, vous ne saurez pas pourquoi les cadres commencent à se planter



2
votes

Vous pouvez vérifier si le type de structure tombe sous n'importe où dans Espace de noms système . Mais encore une fois ce n'est pas une solution fiable.


0 commentaires

3
votes

Mettre les commentaires ci-dessus dans une méthode d'extension:

public static class ReflectionExtensions {
        public static bool IsCustomValueType(this Type type) {            
               return type.IsValueType && !type.IsPrimitive && type.Namespace != null && !type.Namespace.StartsWith("System.");
        }
    }


0 commentaires

-1
votes

Avez-vous une valeur qui va avec ce type? Appelez la méthode tostring et vérifiez si la chaîne renvoyée commence par "{".

Si vous n'avez pas de valeur, vérifiez s'il a un constructeur sans paramètre. Si ce n'est pas le cas, c'est un constructeur. Si tel est le cas, utilisez l'activateur pour créer une instance et appelez à nouveau la méthode tostring .


0 commentaires