Я думаю, что смог ответить на мой вопрос следующим образом:
public static class DecimalExtensions
{
/// <summary>
/// Converts a numeric value to its equivalent currency string representation using the specified culture-specific format information.
/// </summary>
/// <param name="value">The value to be converted.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>The currency string representation of the value as specified by <paramref name="provider" />.</returns>
public static string ToCurrency(this decimal value, IFormatProvider provider) =>
/// Use "1" (or "-1" if value is negative)
/// as a placeholder for the actual value.
(value < 0 ? -1 : 1)
/// Format as a currency using the "C" format specifier.
.ToString("C0", provider)
/// Convert the absolute value to its string representation
/// then replace the placeholder "1".
/// We used absolute value since the negative sign
/// is already converted to its string representation
/// using the "C" format specifier.
.Replace("1", Math.Abs(value).ToString("#,0.############################", provider));
}
Тесты
public class ToCurrencyTests
{
private string ToCurrency(decimal value, string cultureName) =>
value.ToCurrency(CultureInfo.GetCultureInfo(cultureName));
[Theory]
[MemberData(nameof(enUS))]
public void ToCurrency_enUS(decimal value, string expected) =>
Assert.Equal(expected, ToCurrency(value, "en-US"));
[Theory]
[MemberData(nameof(frFR))]
public void ToCurrency_frFR(decimal value, string expected) =>
Assert.Equal(expected, ToCurrency(value, "fr-FR"));
public static TheoryData<decimal, string> enUS =>
new TheoryData<decimal, string>
{
{ 1m, "$1" },
{ 1.0m, "$1" },
{ 1.1m, "$1.1" },
{ 1.10m, "$1.1" },
{ -1m, "($1)" },
{ -1.0m, "($1)" },
{ -1.1m, "($1.1)" },
{ 1000m, "$1,000" },
{ 1000.0m, "$1,000" },
{ 123456789.123456789m, "$123,456,789.123456789" },
{ .0000000000000000000000000001m, "$0.0000000000000000000000000001" }
};
/// <remarks>
/// Note that the group separator used here is a non-breaking space ' ' (i.e. or char 160)
/// </remarks>
public static TheoryData<decimal, string> frFR =>
new TheoryData<decimal, string>
{
{ 1m, "1 €" },
{ 1.0m, "1 €" },
{ 1.1m, "1,1 €" },
{ 1.10m, "1,1 €" },
{ -1m, "-1 €" },
{ -1.0m, "-1 €" },
{ -1.1m, "-1,1 €" },
{ 1000m, "1 000 €" },
{ 1000.0m, "1 000 €" },
{ 123456789.123456789m, "123 456 789,123456789 €" },
{ .0000000000000000000000000001m, "0,0000000000000000000000000001 €" }
};
}
РЕДАКТИРОВАТЬ: скопировать неразрывный пробел здесь http://www.unicode -symbol.com / и / 00A0.html