2010-07-29 6 views
0

J'ai quelques problèmes avec le numéro < -> conversion de chaîne je ne peux pas trier.Quel nombre <-> conversions de chaîne sont toujours cohérentes, sans tenir compte des paramètres de localisation?

Nous avons écrit un cadre de sérialisation qui utilise plusieurs techniques de sérialisation xml. Mais je l'ai vu quelques conversions de nombres incohérents dans la sortie générée:

utilisant:

var c = TypeDescriptor.GetConverter(double); 
var s = c.ConvertToString(value); 

et

var c = TypeDescriptor.GetConverter(double); 
return c.ConvertFromString(value.Value); 

Je reçois des chaînes avec séparateur virgule comme 3,33 et reconvertis en doubles œuvres , mais la conversion en double fonctionnera-t-elle aussi dans un autre pays qui utilise le point comme séparateur? (Je suis en Allemagne, nous utilisons des virgules, mais à part cela, je veux le seperator dot)

Puis dans une autre partie du code i convertir les doubles dans certains struct directement en l'ajoutant à un XElement:

data.Add(new XElement("x", vector.x)); 

Le constructeur XElement convertit le double en chaîne avec un point tel que "3.33".

Il devient vraiment étrange, quand je veux convertir cette chaîne de retour à une double:

Double.TryParse(item.Value, out value.x); 

et

value.x = Convert.ToDouble(item.Value); 

à la fois ignorer le point et j'ai une double valeur de 333 !?

donc je l'ai essayé là aussi avec le code TypeConverter, mais il me donne une exception, que « 3.33 » est aucune chaîne valide pour le double convertisseur ...

Maintenant, ce que je vraiment besoin est un nombre < -> conversion de chaîne qui utilise toujours le séparateur de points et l'analyse également, indépendamment des paramètres de culture/localisation ...

Je suis perdu .. que dois-je utiliser? J'ai même essayé des choses comme:

NumberFormatInfo provider = new NumberFormatInfo(); 

    provider.NumberDecimalSeparator = "."; 
    provider.NumberGroupSeparator = " "; 
    provider.NumberGroupSizes = new int[] { 3 }; 

    foreach (var item in CultureInfo.GetCultures(CultureTypes.AllCultures)) 
    { 
     item.NumberFormat = provider; 
    } 

, mais il n'a pas aidé .. merci pour tout soupçon ..

Répondre

3

Un exemple sur la façon de résoudre ce problème. À supposer que c'est l'original:

double ParseString(string s) 
{ 
    return double.Parse(s); 
} 

c'est un type de solution

double ParseString(string s) 
{ 
    return double.Parse(s, CultureInfo.InvariantCulture); 
} 

ici est vous une autre pouvez utiliser si vous avez un grand nombre de Parsis()

double ParseString(string s) 
{ 
    // Save off previous culture and switch to invariant for serialization. 
    CultureInfo previousCulture = Thread.CurrentThread.CurrentCulture; 
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; 

    double result = double.Parse(s, CultureInfo.InvariantCulture); 

    Thread.CurrentThread.CurrentCulture = previousCulture; 

    return result; 
} 
+0

Je d méfiez-vous de remplacer 'Thread.CurrentCulture' selon le dernier exemple.De toute évidence, ce n'est pas thread-safe et si un autre thread repose sur «CurrentCulture» étant la culture de l'utilisateur, puis * bang *! –

+0

Thread.CurrentCulture ne l'active-t-il pas uniquement pour le thread en cours? –

+0

j'espère que je l'ai fait comme ça maintenant .. quelqu'un peut-il éclaircir ça? – thalm

Questions connexes