Sembra che molte risposte a questa domanda comportano la sostituzione simbolo percentuale della coltura con la stringa vuota, e quindi parsing della stringa risultante come valore numerico.
Forse mi manca qualcosa, ma qui ci sono ancora alcuni casi non gestiti. In particolare, cosa succede se lo PercentDecimalSeparator
è diverso da NumberDecimalSeparator
per la cultura corrente? Cosa succede se lo PercentGroupSeparator
è diverso da NumberGroupSeparator
per la cultura corrente? Cosa succede se lo PercentGroupSizes
è diverso da NumberGroupSizes
?
Indipendentemente dal fatto che tale cultura esista praticamente (se così non fosse, potrebbe benissimo esistere in futuro se la formattazione di una cultura è cambiata), penso che si possa trovare una soluzione migliore al problema se consideriamo questi casi aggiuntivi e speciali.
Ecco un frammento di codice che mostra una situazione in cui le altre risposte (solo sulla base di sostituire il simbolo di percentuale) avrà esito negativo, e un suggerimento per come potrebbe essere fatto meglio correttamente:
// Modify a culture so that it has different decimal separators and group separators for numbers and percentages.
var customCulture = new CultureInfo("en-US")
{
NumberFormat = { PercentDecimalSeparator = "PDS", NumberDecimalSeparator = "NDS", PercentGroupSeparator = "PGS", NumberGroupSeparator = "NGS", PercentSymbol = "PS"}
};
// Set the current thread's culture to our custom culture
Thread.CurrentThread.CurrentCulture = customCulture;
// Create a percentage format string from a decimal value
var percentStringCustomCulture = 123.45m.ToString("p");
Console.WriteLine(percentStringCustomCulture); // renders "12PGS345PDS00 PS"
// Now just replace the percent symbol only, and try to parse as a numeric value (as suggested in the other answers)
var deceptiveNumericStringInCustomCulture = percentStringCustomCulture.Replace(customCulture.NumberFormat.PercentSymbol, string.Empty);
// THE FOLLOWING LINE THROWS A FORMATEXCEPTION
var decimalParsedFromDeceptiveNumericStringInCustomCulture = decimal.Parse(deceptiveNumericStringInCustomCulture);
// A better solution...replace the decimal separators and number group separators as well.
var betterNumericStringInCustomCulture = deceptiveNumericStringInCustomCulture.Replace(customCulture.NumberFormat.PercentDecimalSeparator, customCulture.NumberFormat.NumberDecimalSeparator);
// Here we mitigates issues potentially caused by group sizes by replacing the group separator by the empty string
betterNumericStringInCustomCulture = betterNumericStringInCustomCulture.Replace(customCulture.NumberFormat.PercentGroupSeparator, string.Empty);
// The following parse then yields the correct result
var decimalParsedFromBetterNumericStringInCustomCulture = decimal.Parse(betterNumericStringInCustomCulture)/100m;
Sì, il codice è un po 'più lungo, e forse sono pedante (cioè forse una tale cultura non esisterà mai realmente). Detto questo, mi sembra una soluzione più generale. Spero che aiuti qualcuno :)
Puoi usare 'if (value.EndsWith ("% ")) ...' – Bitterblue
Alcune colture iniziano con percentuali, quindi hai davvero bisogno di CultureInfo.CurrentCulture.NumberFormat –