简体   繁体   中英

String.Format function not working

This seems like a really dumb problem, but I just haven't managed to get around it. Here is the code:

private string[] ConvertToCurrency(string[] costs)
{
    int count = costs.Length;

    for (int i = 0; i < count - 1; i++)
    {
        costs[i] = String.Format("{0:C}", costs[i]);
    }

    return costs;
}

and I expect that the output should be the numbers I'm storing in my string array will be formatted to currency, but they're completely unchanged when they come out the other end.

I have no idea why this is happening, and have tried some other methods to format it but nothing.

您应该这样做, {0:C}用于货币格式,它将应用于数值。

costs[i] = String.Format("{0:C}", Convert.ToDecimal(costs[i]));

Full explanation:

When you have an item like {0:C} in your string, then the C part is a format string. To quote the documentation :

If formatString is present, the argument referenced by the format item must implement the IFormattable interface (my emphasis)

An IFormattable object like double or decimal has an overload of ToString that takes in a string, which could then be "C" in your case. So it translates to something like yourFormattableThing.ToString("C", null) .

However, when you look at the documentation for string , you see that a string (like your costs[i] ) is not IFormattable , and a string does not possess a ToString that takes in a format string. So you are violating the "must implement" from my quote above.

Instead of raising an exception, String.Format chooses to ignore your C part.

So there's your explanation of what's going wrong.

Now, to make things work, if your string is really a number, convert/parse it to an IFormattable object like decimal or double , and then use the "C" format string on the numeric type.

It is because parameter string[] costs type is string so it will not format the number as you expect. You have to change the parameter type to number (int, long, float, double, etc) or you have to convert the value to numeric type before you format it.

var val = Convert.ToInt32(costs[i]);
costs[i] = String.Format("Value is: {0:C}", val);
public static class StringExtensions
{
    /// <summary>
    /// Formats a string using the string.Format(string, params object[])
    /// </summary>
    /// <param name="helper">The string with the format.</param>
    /// <param name="args">The value args.</param>
    /// <returns>The formatted string with the args mended in.</returns>
    public static string Mend(this string helper, params object[] args) => string.Format(helper, args);

}

// Usage: "Zero: {0}, One: {1}, Two: {2}".Mend("0", "1", "2");

Building on the previous answers this seems like the perfect place to introduce linq:

private IEnumerable<String> ConvertToCurrency(IEnumerable<String> costs)
{
 return costs.Select(c => String.Format("{0:C}", Convert.ToDecimal(c)));
}

So in this case it will still work on arrays in exactly the same way, but makes the logic accessible to Lists/Queue's etc... If you want to eager execute add a ToArray() after the select.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM