11
votes

Obtenir du type de données des valeurs passées en chaîne

J'écris un cadre qui se connectera à de nombreux types de source de données et de valeurs de retour de ces sources. Les eaux faciles sont SQL, Access et Oracle. Les plus difficiles sont SharePoint, CSV.

Si je retourne des valeurs de sources de texte, je voudrais déterminer le type de données des données.

Étant donné qu'un CSV est tout le texte, il n'y a pas de métadonnées à interroger, je devrais analyser la données d'une manière utaire de déterminer le type de données.

exemple:

liste de "vrai", "vrai", "faux", "faux" serait booléen
Liste de "1", "0", "1", "0" serait booléen
Liste des "1", "4", "-10", "500" serait entier
Liste des "15.2", "2015.5896", "1.0245", "500" serait double
Liste des "2001/01/01", "2010/05/29 12:00", "1989/12/25 10:34:21" serait DateTime

Il est basé sur https : //stackoverflow.com/questions/606365/c-doubt-finding-the-DaTaType/606381#606381 xxx

EDIT: Je n'ai que besoin de répondre Pour ce qui suit: xxx

pouvez-vous voir une éventuelle amélioration de la priorité?


7 commentaires

Pour l'enregistrement, boolean.tryparse échouera pour 1 ou 0, il convertira uniquement true ou false .


"Depuis qu'un CSV est tout le texte, il n'y a pas de métadonnées à interroger" - pas nécessairement vrai. Si vous avez le contrôle de la CSV, vous pouvez faire la première ligne décrire les types de données des différentes positions classées ou si elle varie selon la ligne, vous pourriez avoir un champ au début de la rangée ou similaire. Ce n'est peut-être pas que ce n'est pas possible mais j'aurais pensé que pour tout CSV donné, vous devriez avoir quelque chose quelque part qui vous dit quels sont les champs ...


Pas de contrôle sur le CSV. Merci tout de même pour ta contribution!


@Dimi Quel genre de solution "moderne" attendriez-vous?


@Evk quelque chose est mieux qui marqué comme une réponse ici. Quelque chose est plus compact par exemple.


@Dimi je vois répondre à une question complète des doublons, plus il existe une fonction getcolumnType. Vous voulez alternative à ce getcolumnType?


@Evk j'ai besoin de types C #. Merci.


5 Réponses :


1
votes

serait-il plus facile de le stocker dans un type de données générique avec .toint16 (), .toint32 (), .tobool (), etc.? Si vous écrivez une application s'attend à INT et que cela devienne booléen, cela échouera, il serait donc préférable de laisser le programmateur explicitement converti au type de données attendu.

Le problème avec votre approche est que vous ne savez pas si une ligne contenant 0 en tant que premier élément contiendra -100000 comme numéro d'article 100. Cela signifie que vous ne pouvez pas faire une conversion réussie tant que toutes les lignes n'aient pas été tryparsed tous les différents types de données. Opération très coûteuse!

Si quelque chose j'utilise des expressions régulières précompilées et / ou une logique personnalisée pour traiter les données. Par exemple, itérant toutes les lignes pour trouver le nombre le plus élevé / le plus bas, l'occurrence de la chaîne, etc.


1 commentaires

Je n'ai aucun contrôle sur le type de stockage: il s'agit de fonctionnalités d'importation de données. Pendant les clients d'exécution, les clients importeront des données provenant de nombreuses sources possibles, et les types doivent correspondre entre la source et la cible. Je dois fournir des informations de type de données avec les données source avant qu'une cible ne soit sélectionnée pour effectuer la sélection des champs cibles en fonction des types de données. Votre idée de trouver le plus haut / le plus bas semble une étape dans la bonne direction: merci!



1
votes

À partir des types les plus étroits et de travailler vers la plus large peut ne pas être la meilleure approche. Si je savais quoi que ce soit sur les données, je commencerais avec le type le plus fréquent et travailler au moins. Si cela ne le savait pas, je pourrais ou non faire des recherches pour avoir une idée de ce que cela pourrait être statistiquement, si possible. Sinon je voudrais juste faire de mon mieux. Pourquoi tester un bit ou DateTime tôt si vous ne vous attendez qu'autrement une fois tous les 10 000 enregistrements?


1 commentaires

Points valides, mais comme je vais tester jusqu'à un maximum de 52 lignes (rangée 1 à 50 + la plus courte + la plus longue) par colonne pour chaque importation, l'impact de la performance est négligeable.



19
votes

J'ai proposé la solution suivante qui fonctionne: xxx


0 commentaires

3
votes
    List<Type> types = new List<Type>(new Type[] {
        typeof(Boolean)
        , typeof(int)
        , typeof(double)
        , typeof(DateTime)
    });
    string t = "true";
    object retu;
    foreach (Type type in types)
    {
        TypeConverter tc = TypeDescriptor.GetConverter(type);
        if (tc != null)
        {
            try
            {
                object obj = tc.ConvertFromString(t); // your return value;
            }
            catch (Exception)
            {
                continue;
            }
        }
    }

3 commentaires

Merci pour votre contribution. Cependant, en utilisant un try-capity pour contrôler le flux de votre code est une mauvaise pratique. En utilisant des exceptions comme flux de contrôle comme cela rend difficile de déboguer un programme. Les debuggers sont souvent configurés pour s'arrêter à toute exception, qu'il soit manipulé ou non. Beaucoup d'exceptions «attendues» rendent cela plus difficile. Des exceptions ne devraient jamais être attendues, elles devraient être exceptionnelles; C'est pourquoi ils s'appellent "exceptions". La capture attrape tout, y compris des choses qui indiquent probablement une erreur fatale qui devrait être signalée à l'utilisateur. (Crédit à Eric Lippert)


Je suis d'accord avec ce commentaire pour les cas communs. Mais dans ce cas, non, car TypeDeScriptor ne permet pas de «essayer» de convertir une chaîne et renvoyez tout indicateur du résultat de convertir, jette juste une exception. Cette solution fonctionne. BTW dans d'énormes projets Debuggers doit être configuré pour attraper non manipulé une exception, pas toutes jetée. Exception - Dans de nombreux cas, c'est la marque que quelque chose qui ne va pas dans le blocage, mais il ne dit jamais que cela doit être une erreur fatale. Exemple, mon code - Exception ne jette que lorsque la chaîne ne convient pas à un type converti.


C'est votre décision d'utiliser ma solution ou non. Vous avez besoin de meilleure solution, ni le tien, je l'ai donné.



13
votes

Puisque DIMI a mis une prime et a besoin de solution plus "moderne", je vais essayer de en fournir un. Tout d'abord, de quoi avons-nous besoin d'une classe raisonnable qui convertit des chaînes à des trucs différents?

Comportement raisonnable avec des types de base.

Respectez les informations de culture, surtout lors de la conversion des nombres et des dates.

Possibilité d'étendre la logique avec des convertisseurs personnalisés si nécessaire.

En tant que bonus, évitez de longues chaînes "si", car elles sont assez sujettes à une erreur. xxx

Utilisez comme ceci: xxx


0 commentaires