2010-11-08 6 views
1

J'ai regardé les différentes options qui semblent être disponibles sur le framework .NET (je pense). En particulier, je l'ai regardé 1. TypeConverter 2. Convert.Toxxx 3. Convert.ChangeTypeChangeType, Convert - Conversion d'un type à un autre

Chacun d'entre eux pour une raison ou une autre ne travaille pas pour moi. Je suis assez surpris qu'il ne semble pas y avoir de solution dans le framework .NET pour ce genre de choses. Je suppose que je ne suis pas le seul à en avoir besoin;)

Voici ce que j'essaie de faire. Essentiellement, j'ai un tas de formulaires html qui sont utilisés dans une application. Ces formulaires permettent aux utilisateurs d'entrer des données (évidemment) et j'ai besoin d'extraire ces données dans différents types de données.

Ces types de données sont des types simples, des types primitifs, des types de valeurs, des types de référence et des types de référence personnalisés. En d'autres termes: 1. Int32, Int64, double, décimal, DateTime etc. 2. Int32 [], double [], chaîne [] et éventuellement d'autres tableaux de types primitifs 3. divers objets DTO personnalisés qui ont les éléments ci-dessus types en tant que propriétés.

La "entrée" est sous la forme d'une chaîne de caractères typiquement depuis que je suis en terre. Pour vous donner une idée des raisons pour lesquelles les solutions existantes ne fonctionnent pas pour moi, jetez un oeil à l'adresse suivante entrées « chaîne » nécessitant une conversion

  1. « 1,234 » -> Int32
  2. « 1,234 $ » -> Int32
  3. "$ 1,234", ce -> int32
  4. "" -> int32
  5. "1,2,3,4,5" -> Int32 []
  6. "0" ou "false" OU " False "OU" off "-> Boolean false

Je sais comment convertir chacun de ces cas à la main, mais je cherche quelque chose qui fait partie du cadre que j'ai manqué ou une solution décente qui gère les types d'entrées énumérées ci-dessus.

+0

Je pense que la raison pour laquelle vous ne trouvez pas ce que vous cherchez est que ce que vous décrivez est un nombre arbitraire de "règles" pour convertir un nombre arbitraire de types de données. Il ne serait tout simplement pas possible de tenter cela au niveau du cadre, car il y aurait toujours des cas limites qui ne fonctionneraient pas. Ce que je ferais est de créer une classe de conversion spéciale qui connaît ces cas spéciaux et les manipule (avant de passer par défaut à TypeConverter.ChangeType, etc ...). Ensuite, vous pouvez réutiliser ce code là où vous en avez besoin. – Chris

Répondre

1

Jackie,

Ceci est une exigence très courante dans le monde du développement Web et que vous l'avez remarqué, il n'y a aucun moyen intégré pour atteindre cet objectif et ce qui est là est loin dans le plus simple des cas.

@Chris ces règles ne sont pas arbitraires par aucun coup de l'imagination. Ils sont en fait très communs quand il s'agit de traiter les entrées des utilisateurs, en particulier sur le web. En fait, les conversions booléennes sont également assez courantes étant donné que les cases à cocher dans ASP.NET retournent on/off (pour une raison quelconque).

Vous avez plusieurs options. L'une est une approche simpliste et l'autre une solution extensible. Tout commence à partir de la façon dont vous souhaitez utiliser cette fonctionnalité à partir de votre application. Puisque vous n'avez pas fait beaucoup de lumière sur ce que vous faites actuellement ou sur ce que vous aimeriez faire, j'ai pris la liberté de faire quelques suppositions.

La première hypothèse étant que les valeurs vous parviennent via Request.Form ou Request.QueryStrings (les deux étant NameValueCollections pouvant contenir plusieurs valeurs pour un nom donné). Supposons que vous aimeriez une méthode appelée ChangeType qui donne un nom aux paramètres et le type que vous souhaitez modifier pour retourner la valeur en tant que type requis. Ainsi, la signature de la méthode pourrait ressembler à ceci:

public T ChangeType<T>(string parameterName, T defaultValue = default(T))

Et vous pouvez l'utiliser comme ceci:

int someId = ChangeType<int>("id", -1); 

Ainsi, la valeur de la someId variables sera soit la valeur extraite de demande. Formulaire ou Request.QueryStrings sous la forme d'un int (s'il existe) ou -1 si ce n'est pas le cas.

Une mise en œuvre plus complète est la suivante:

static T ChangeType<T>(string value) where T: struct 
{ 
    Type typeOft = typeof(T); 
    if (String.IsNullOrEmpty(value.Trim())) 
    return default(T); 
    if (typeOft == typeof(Int32)) 
    return (T)ConvertToInt32(value); 
    else if (typeOft == typeof(Int64)) 
    return (T)ConvertToInt64(value); 
    else if (typeOft == typeof(Double)) 
    return (T)ConvertToDouble(value); 
    else if (typeOft == typeof(Decimal)) 
    return (T)ConvertToDecimal(value); 
    return default(T); 
} 

static object ConvertToInt32(string value) 
{ 
    return Int32.Parse(value, 
    NumberStyles.Currency^NumberStyles.AllowDecimalPoint); 
} 

static object ConvertToInt64(string value) 
{ 
    return Int64.Parse(value, 
    NumberStyles.Currency^NumberStyles.AllowDecimalPoint); 
} 

static object ConvertToDouble(string value) 
{ 
    return Double.Parse(value, NumberStyles.Currency); 
} 

static object ConvertToDecimal(string value) 
{ 
    return Decimal.Parse(value, NumberStyles.Currency); 
} 

Si vous devez être capable de gérer plusieurs types, mettre en œuvre simplement la méthode requise (comme ConvertToInt32 par exemple) et ajouter une autre condition autre dans le ChangeType<T> méthode et vous avez terminé. Maintenant, si vous cherchez une solution extensible de sorte que vous pouvez ajouter des fonctionnalités supplémentaires sans avoir à modifier le code principal et être capable de gérer vos propres types personnalisés, alors s'il vous plaît jeter un oeil à ce blog. [ChangeType - Modification du type d'une variable en C#] [1] http://www.matlus.com/2010/11/changetypet-changing-the-type-of-a-variable-in-c/

Hope this Helps.

+0

merci! C'est exactement ce que je cherchais. La solution simple est sympa mais la solution extensible est vraiment sympa. Merci aussi pour l'écriture et le code.Je l'ai déjà branché sur mon code et ça fonctionne comme un charme (avec quelques modifications d'espace de noms). –

+0

Je crains de pouvoir voter pour votre réponse, car je n'ai pas encore la réputation. –

+0

Jackie, pas de problème (à propos du vote). Je suis nouveau ici aussi :) –

1

Tous les types primitifs tels que int et bool ont un TryParse static method que vous pouvez utiliser pour eux. Cela fera vos affaires Int32 pour vous:

Int32 temp = 0; 
Int32.TryParse(myStringInput, out temp); 

Les TryParse() renvoie une valeur booléenne indiquant si l'analyse syntaxique a réussi ou non, afin que vous puissiez tester pour cela et prendre des mesures si vous voulez, ou tout simplement faire comme je l'ai fait ci-dessus et ont une valeur par défaut si le TryParse échoue. Le TryParse est particulièrement utile car il ne lance pas d'exception s'il échoue (il renvoie simplement false à la place).

Le bool.TryParse() ne va pas traduire directement un 0 numérique en tant que false - vous devez jeter une première chaîne:

bool x = true; 
bool.TryParse(0.ToString(), out x); 
Console.WriteLine("x is {0}", x); 

Traduire la valeur de chaîne hors ou sur à un booléennes exiger votre propre fonction pour l'interpréter.

+0

slugster, merci pour la réponse. Je sais comment convertir tous les exemples aux types dont j'ai besoin. Je cherchais soit une classe .net/utilitaire qui le fait déjà, soit une solution farily générique et/ou extensible. –

Questions connexes