11

String formatting in C#;

Can I use it? Yes.

Can I implement custom formatting? No.

I need to write something where I can pass a set of custom formatting options to string.Format, which will have some effect on the particular item.

at the moment I have something like this:

string.Format("{0}", item);

but I want to be able to do things with that item:

string.Format("{0:lcase}", item); // lowercases the item
string.Format("{0:ucase}", item); // uppercases the item
string.Format("{0:nospace}", item); // removes spaces

I know I can do things like .ToUpper(), .ToLower() etc. but I need to do it with string formatting.

I've been looking into things like IFormatProvider and IFormattable but I don't really know if they are the things I should be using, or, how to implement them.

Can anyone explain how I can solve this problem?

Rationale (just in case you want to know...)

I have a small program, where I can enter a comma delimited set of values, and a template. The items are passed into string.Format, along with the template which creates an output. I want to provide template formatting options, so that the user can control how they want items to be output.

3

1 Answer 1

15

You can make a custom formatter, something like:

public class MyFormatter : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType)
   {
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }

   public string Format(string fmt, object arg, IFormatProvider formatProvider) 
   {
       if(arg == null) return string.Empty;

       if(fmt == "lcase")
           return arg.ToString().ToLower();
       else if(fmt == "ucase")
           return arg.ToString().ToUpper();
       else if(fmt == "nospace")
           return arg.ToString().Replace(" ", "");
       // Use this if you want to handle default formatting also
       else if (arg is IFormattable) 
           return ((IFormattable)arg).ToString(fmt, CultureInfo.CurrentCulture);
       return arg.ToString();
   }
}

Then use it like:

 string.Format(new MyFormatter(),
            "{0:lcase}, {0:ucase}, {0:nospace}", 
            "My Test String")

This should return:

my test string, MY TEST STRING, MyTestString

Sign up to request clarification or add additional context in comments.

9 Comments

Shouldn't you be passing the formatProvider in the IFormattable ToString? And shouldn't you check if arg is IFormattable first and then do the additional custom formatting?
@juharr No to both questions: the passed formatProvider in this example would be our same object, so it'd loop indefinitely: we are passing a default formatter (CurrentCulture) to handle default formatting. The fact that is IFormattable only differs from object in that we can actually pass an IFormatProvider to ToString(), so if we are not doing so in the rest of ToString() calls, there's no need for it to be IFormattable. One could extend this ICustomFormatter to accept a "chained" IFormatProvider and then we'd do as you say, but in this case, it is not necessary.
@juharr of course, this is a very simple implementation just addressed to answer the question :-)
i have delete my answer as the un reasonable down vote discourage me to give solutions... :(
@SathikKhan for the record, I hadn't downvoted you (so I'm not sure why you write that on a comment to my answer), but since your answer was, a) very little informative ("use XSLT" and basically that's all there was to it), and b) incorrect (since XSLT is for transforming XML files, and nowhere in the question does it say he's using XML), I guess the downvotes were kinda correct
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.