Obtenir le type de données à partir des valeurs passées comme une chaîne de caractères
Je suis en train d'écrire un cadre qui permettra de se connecter à de nombreux différents types de sources de données et les valeurs de retour de ces sources. Les plus simples sont SQL, Access et Oracle. Les plus sévères sont Sharepoint, CSV.
Si je les valeurs de retour de texte en fonction des sources, je tiens à déterminer le type de données de données.
Depuis un fichier CSV est tout le texte, il n'y a pas de métadonnées pour interroger, j'aurais besoin d'analyser les données d'une certaine manière à déterminer le type de données.
Exemple:
Liste de "vrai", "true", "false", "false" serait boolean
Liste des "1", "0", "1", "0" serait boolean
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
object ParseString(string str)
{
Int32 intValue;
Int64 bigintValue;
double doubleValue;
bool boolValue;
DateTime dateValue;
//Place checks higher in if-else statement to give higher priority to type.
if (Int32.TryParse(str, out intValue))
return intValue;
else if (Int64.TryParse(str, out bigintValue))
return bigintValue;
else if (double.TryParse(str, out doubleValue))
return doubleValue;
else if (bool.TryParse(str, out boolValue))
return boolValue;
else if (DateTime.TryParse(str, out dateValue))
return dateValue;
else return str;
}
Edit: j'ai seulement besoin de répondre à la suivante:
BIT
DATETIME
INT
NVARCHAR(255)
NVARCHAR(MAX)
BIGINT
DECIMAL(36, 17)
Vous voyez des améliorations possibles à la priorité?
Boolean.TryParse
échoue pour 1 ou 0, il vous permet de convertir seulement true
ou false
."Depuis un fichier 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 que vous pourriez faire de la première ligne de décrire les types de données des différents déposé positions ou s'il varie, par ligne, alors vous pourriez avoir un champ au début de la ligne ou similaire. Il est peut-être ce n'est pas possible, mais j'aurais pensé que pour toute CSV, vous devriez avoir quelque chose quelque part qui vous dit que les champs sont...
Aucun contrôle sur le format CSV. Merci pour vos commentaires!
quel genre de "moderne" solution attendez-vous?
Quelque chose est mieux que marqué comme réponse ici. Quelque chose de plus compact par exemple.
OriginalL'auteur callisto | 2011-03-15
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé la solution suivante qui fonctionne:
OriginalL'auteur callisto
Depuis Dimi mettre un bounty et a besoin de plus "moderne" de la solution, je vais essayer d'en fournir un. Tout d'abord, que faut-il raisonnable de classe qui convertit les chaînes de choses différentes?
D'un comportement raisonnable avec des types de base.
L'égard d'info culture, en particulier lors de la conversion des nombres et des dates.
Possibilité d'étendre la logique personnalisée avec des convertisseurs si nécessaire.
Comme un bonus, éviter les longs "si" chaînes " car ils sont très sujettes à l'erreur.
Utiliser comme ceci:
OriginalL'auteur Evk
Je suis d'accord avec ce commentaire pour les cas courants. Mais dans ce cas, non, parce que TypeDescriptor n'autorise pas à "essayer" convertir en chaîne de caractères, et renvoyer n'importe quel drapeau de la convertir résultat, déclenche une exception. Cette solution fonctionne. BTW dans d'énormes projets débogueurs doit être configuré pour attraper ce n'est pas manipulé exception, pas tous jetés. Exception - dans de nombreux cas, c'est la marque que quelque chose de mal dans le bloc try, mais il ne dit jamais qu'il doit être erreur fatale. Exemple, mon code d'exception déclenche uniquement lorsque la chaîne ne s'adapte pour un type de convertir.
Il est de votre décision d'utiliser ma solution ou pas. Vous aviez besoin d'une meilleure solution, ni la vôtre, j'ai donné.
upvoted pour en indiquant votre défense.
OriginalL'auteur zabulus
Serait-il plus facile de le stocker dans un générique de type de données .ToInt16(), .ToInt32(), .ToBool(), etc.? Si vous écrivez une application attend int et il obtient boolean ce sera un échec, de sorte qu'il serait préférable de laisser le programmeur explicite convertir le type de données attendu.
Le problème avec votre approche, c'est que vous ne savez pas si une ligne contenant des 0 comme le premier élément contient -100000 comme numéro d'article 100. Cela signifie que vous ne pouvez pas faire un succès de la conversion jusqu'à ce que toutes les lignes ont été TryParsed par tous les différents types de données. Opération très coûteuse!
Si quelque chose que je voudrais utiliser précompilés expressions régulières et/ou logique personnalisée pour traiter les données. Par exemple itération toutes les lignes pour trouver le plus haut/le plus bas nombre, l'occurence de la chaîne, etc.
OriginalL'auteur Tedd Hansen
En commençant par le plus étroit de types et de travail vers le plus large ne peut pas être la meilleure approche. Si je savais quelque chose sur les données, j'aimerais commencer avec les plus fréquentes type, et de travailler vers le moins. Si si ne savais pas que j'avais pourrait ou ne pourrait pas faire une recherche pour avoir une idée de ce que pourrait être statistiquement, si possible. Autre chose que je voudrais faire de mon mieux deviner. Pourquoi tester pour peu ou datetime tôt si vous ne vous attendez à se produire une fois tous les 10 000 enregistrements?
OriginalL'auteur mickeyf