tags:

views:

284

answers:

5

Does anyone know how to construct a format string in .NET so that the resulting string contains a colon?

In detail, I have a value, say 200, that I need to format as a ratio, i.e. "1:200". So I'm constructing a format string like this "1:{0:N0}" which works fine. The problem is I want zero to display as "0", not "1:0", so my format string should be something like "{0:1:N0;;N0}", but of course this doesn't work.

Any ideas? Thanks!

+1  A: 

How about this:

String display = (yourValue == 0) ? "0" : String.Format("1:{0:N0}", yourValue);
Andrew Hare
A: 

Well, one way is to put it in an if statement, and format it differently if it is zero.

Robert Harvey
+1  A: 
String.Format(n==0 ? "{0:NO}" : "1:{0:NO}",n);
Tim Hoolihan
+3  A: 

You can use AakashM's solution. If you want something slightly more readable, you can create your own provider:

internal class RatioFormatProvider : IFormatProvider, ICustomFormatter
{
    public static readonly RatioFormatProvider Instance = new RatioFormatProvider();
    private RatioFormatProvider()
    {

    }
    #region IFormatProvider Members

    public object GetFormat(Type formatType)
    {
        if(formatType == typeof(ICustomFormatter))
        {
            return this;
        }

        return null;
    }

    #endregion

    #region ICustomFormatter Members

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        string result = arg.ToString();

        switch(format.ToUpperInvariant())
        {
            case "RATIO":
                return (result == "0") ? result : "1:" + result;
            default:
                return result;
        }
    }

    #endregion
}

With this provider, you can create very readable format strings:

int ratio1 = 0;
int ratio2 = 200;
string result = String.Format(RatioFormatProvider.Instance, "The first value is: {0:ratio} and the second is {1:ratio}", ratio1, ratio2);

If you control the class being formatted (rather than a primitive one like Int32), you can make this look nicer. See this article for more details.

Jeff Moser
I don't have a compiler right now so I can't test it, but I suppose you could also write it as an extension method? Something like "String.FormatRatio(..)"?
Pedro d'Aquino
You could certainly do it that way too. jemnery just indicated that he wanted a format string approach.
Jeff Moser
+6  A: 
using System;

namespace ConsoleApplication67
{
    class Program
    {
        static void Main()
        {
            WriteRatio(4);
            WriteRatio(0);
            WriteRatio(-200);

            Console.ReadLine();
        }

        private static void WriteRatio(int i)
        {
            Console.WriteLine(string.Format(@"{0:1\:0;-1\:0;\0}", i));
        }
    }
}

gives

1:4
0
-1:200

The ; separator in format strings means 'do positive numbers like this; negative numbers like this; and zero like this'. The \ escapes the colon. The third \ is not strictly necessary as a literal zero is the same as the standard numeric format output for zero :)

AakashM
Nice. I hadn't seen the ';' syntax before.
Jeff Moser
Ah, perfect - it's the string literal we were missing - we'd actually tried esacaping the colon but of course that doesn't compile without @-ing the string. Cheers AakashM.
Excellent answer!
Gordon Mackie JoanMiro