Custom string formatter in C#
Asked Answered
C

1

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.

Chisholm answered 23/2, 2016 at 11:57 Comment(3)
What type can item have? See String.Format - how it works and how to implement custom formatstrings.Bainbrudge
@Bainbrudge item is a string (see rationale)Chisholm
How about ICustomFormatterInter
H
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

Heida answered 23/2, 2016 at 12:12 Comment(9)
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?Episcopacy
@Episcopacy 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.Heida
@Episcopacy of course, this is a very simple implementation just addressed to answer the question :-)Heida
i have delete my answer as the un reasonable down vote discourage me to give solutions... :(Casteel
@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 correctHeida
Sorry @Jcl, it doesn't mean to you. First, don't encourage people to use hardcode the conditions inside. Find an answer for these a) Why MS offering you to convert the dataset as XML? b) Did you tried to solve this problem using xslt? By doing b and thinking more a you will get to know few parsing will give you the best solution. NOTE: I never down vote anyones solution because no solution is INCORRECT.Casteel
@SathikKhan the problem is that you are assuming a DataSet here, and XML, where the OP hasn't mentioned neither at all. Yes, of course, XSLT can be used, but it would mean a rather convoluted and unperformant solution (transform whatever text you are using to an XML document, then make the XSLT transform, then parse the XML document back?) to a very specific problem. Add to that, that your answer was basically just a hint without any specific solution, and I can see where the downvotes were coming. Again, I didn't downvote it, but I can see where they came fromHeida
@SathikKhan and I think there are incorrect solutions, but Stack Overflow comments are not the best place to debate around that. You can always ask for oppinions at meta.stackoverflow.comHeida
@Jcl, not indent to take this as a debate but just wanna share my view. Thanks.Casteel

© 2022 - 2024 — McMap. All rights reserved.