web-dev-qa-db-fra.com

Culture invariante Decimal.TryParse ()

J'écris une chaîne personnalisée dans le validateur décimal qui doit utiliser Decimal.TryParse qui ignore la culture (c'est-à-dire ne se soucie pas si l'entrée contient "." Ou "," comme séparateur de virgule décimale). Voici la méthode suggérée:

public static bool TryParse(
    string s,
    NumberStyles style,
    IFormatProvider provider,
    out decimal result
)

Je ne sais pas quoi utiliser comme troisième paramètre. Les exemples que j'ai vus ressemblent à ceci:

culture = CultureInfo.CreateSpecificCulture("en-GB");
Decimal.TryParse(value, style, culture, out number)

ils créent donc une culture spécifique. CultureInfo n'a pas de méthode "CreateInvariantCulture" et CultureInfo.InvariantCulture n'est pas du type requis. Quelle est la bonne utilisation?

30
Shaggydog

Essayez comme ceci:

decimal value;
bool b = Decimal.TryParse("0.1", NumberStyles.Any, new CultureInfo("en-US"), out value);

La meilleure façon serait probablement d'utiliser la méthode Decimal.Parse () comme vous le feriez traditionnellement avec n'importe quelle valeur de chaîne décimale.

Vous pouvez utiliser NumberStyles.Currency pour spécifier que les valeurs doivent être lues en tant que devise, ce qui prendra en charge toutes les valeurs liées à la devise (vous devrez ajouter une référence à System.Globalalization pour utiliser ceci:

using System.Globalization;

Decimal.Parse accepte également un troisième paramètre, qui vous permettra de définir explicitement le IFormatProvider si vous le souhaitez et que vous souhaitez une culture spécifique:

decimal value = Decimal.Parse(currency, NumberStyles.Currency, CultureInfo.InvariantCulture); //yields 15.55
50
Nayeem Mansoori

Mes méchants. J'ai testé le code suivant:

        string DutchDecimal = "1,5";
        string EnglishDecimal = "1.5";
        decimal a;
        decimal b;
        Console.WriteLine(decimal.TryParse(DutchDecimal, out a));
        Console.WriteLine(a);
        Console.WriteLine(decimal.TryParse(EnglishDecimal, out b));
        Console.WriteLine(b);
        Console.Read();

et il analyse correctement les deux chaînes. Il semble que le TryParse par défaut soit en effet invariant à la culture. J'ai supposé que ce n'était pas le cas, car le TypeConversionValidator par défaut dans EnterpriseLibrary dépendait de la culture et j'ai supposé qu'il utilisait simplement TryParse. Cependant, il s'avère que cet analyseur par défaut est codé en dur pour utiliser la culture actuelle.

EDIT: J'ai découvert que "1.5" convertit en 1.5 et "1.5" convertit en 15. C'est en fait correct pour le comportement invariant de la culture, donc il est là. Toute cette question a apparemment été engendrée par ma méconnaissance du fonctionnement de l'invariant culturel.

7
Shaggydog

En réalité CultureInfo.InvariantCulture peut être utilisé ici. Le paramètre attend IFormatProvider, une interface que CultureInfo implémente. Mais InvariantCulture est invariant dans le sens où il ne varie pas avec les paramètres de l'utilisateur.

En fait, aucune culture n'accepte non plus , ou . comme séparateur décimal - ils sont tous l'un ou l'autre. Vous devrez trouver un autre moyen de traiter les données qui peuvent utiliser l'un de ces séparateurs décimaux.

4
David Heffernan

Je ne sais pas quoi utiliser comme troisième paramètre.

Parce que toutes les cultures NumberDecimalSeparator ou NumberGroupSeparator etc. ne sont pas les mêmes.

Quelqu'un utilise . en tant que NumberDecimalSeparator, quelqu'un utilise , mais il n'y a pas de CultureInfo qui utilise les deux comme NumberDecimalSeparator.

CultureInfo implémente l'interface IFormatProvider . C'est pourquoi si vous spécifiez votre CultureInfo, votre chaîne value essaie d'être analysée selon les règles de cette culture.

J'écris une chaîne personnalisée dans le validateur décimal qui doit utiliser Decimal.TryParse qui ignore la culture

Dans ce cas, vous pouvez utiliser CultureInfo.Clone method pour copier la culture souhaitée (ou InvariantCulture ) et vous pouvez définir NumberDecimalSeparator et NumberGroupSeparator quelle chaîne vous souhaitez.

1
Soner Gönül