String.Format - how it works and how to implement custom formatstrings
Asked Answered
C

7

82

With String.Format() it is possible to format for example DateTime objects in many different ways. Every time I am looking for a desired format I need to search around on Internet. Almost always I find an example I can use. For example:

String.Format("{0:MM/dd/yyyy}", DateTime.Now);          // "09/05/2012"

But I don't have any clue how it works and which classes support these 'magic' additional strings.

So my questions are:

  1. How does String.Format map the additional information MM/dd/yyyy to a string result?
  2. Do all Microsoft objects support this feature?
    Is this documented somewhere?
  3. Is it possible to do something like this:
    String.Format("{0:MyCustomFormat}", new MyOwnClass())
Coif answered 9/5, 2012 at 8:20 Comment(1)
You can have a look at this codeproject.com/Articles/6533/Custom-String-Formatting-in-NETDaguerreotype
F
91

String.Format matches each of the tokens inside the string ({0} etc) against the corresponding object: https://learn.microsoft.com/en-us/dotnet/api/system.string.format#overloads

A format string is optionally provided:

{ index[,alignment][ : formatString] }

If formatString is provided, the corresponding object must implement IFormattable and specifically the ToString method that accepts formatString and returns the corresponding formatted string: https://learn.microsoft.com/en-us/dotnet/api/system.iformattable.tostring

An IFormatProvider may also be used to capture basic formatting standards/defaults etc. Examples here and here.

So the answers to your questions in order:

  1. It uses the IFormattable interface's ToString() method on the DateTime object and passes that the MM/dd/yyyy format string. It is that implementation which returns the correct string.

  2. Any object that implement IFormattable supports this feature. You can even write your own!

  3. Yes, see above.

Fike answered 9/5, 2012 at 8:27 Comment(3)
+1 for linking to the documentation. "Searching around on the internet" can be OK. But when you need deeper understanding, you should Read The Manual.Blinnie
Nice answer but can you tell me where I can find for each class which implements IFormattable, where I can find the allowed formatStrings. For example DateTime supports (on top of my head) y M d h m s and more. Nummeric types supports C from currency but that't all I know from searching arround and not by looking at the Microsoft documentation.Coif
@Coif Formatting TypesTherine
I
21

From my understanding, you would need to implement IFormattable in your class to support this. That then has the method, ToString which takes the parameters you pass into String.Format.

Here is an example.

// Define other methods and classes here
public class Sample : IFormattable
{
     public string ToString(string format, IFormatProvider provider)
     {
         return String.Concat("Your custom format was ", format);
     }
}

String.Format("{0:MyCustomFormat}", new Sample())
Icicle answered 9/5, 2012 at 8:26 Comment(0)
K
5
  1. Check the official MSDN docs, there is a full list of DateTime format strings here: http://msdn.microsoft.com/en-us/library/az4se3k1.aspx. There are indeed quite a few "magical" strings.

  2. As far as I know not all types have "interesting" formatting, but all types support ToString(). If you needed to format a built in object you could add an extension method to do it, but usually formatting is provided in any place where it is needed (or to put it another way, I have only written custom formatters for my own types).

  3. Yes, you can write your own and if you have data that can be formatted in different ways you probably should write a custom formatter by implementing IFormattable, again see the docs here: http://msdn.microsoft.com/en-us/library/system.iformattable.aspx. It's fairly simple, you simply check the strings provided and write out your data based on these, there's no magic behind the scenes:-)

Kandace answered 9/5, 2012 at 8:28 Comment(0)
C
4

Under the covers String.Format does something as follows,

IFormattable formattable = objectToFormat as IFormattable;
if (formattable != null)
{
    formattable.ToString(objectToFormat);
}
else
{
    objectToFormat.ToString();
}

For your questions,

  1. How does String.Format map the additional information MM/dd/yyyy to a string result?

    As specified above, it just calls the IFormattable .ToString(string format, IFormatProvider provider). The provider is often something that tells you what the culture is of your system. Often null because people don't pass it String.Format() as you did in your case.

  2. Does all microsoft objects support this feature? Is this documented somewhere?

    Anything that implements IFormattable does.

  3. Is it possible to do something like this: String.Format("{0:MyCustomFormat}, new MyOwnClass())

    Essentially if you want your own object to do something with the format provided you implement IFormattable.

There are a huge number of supporting classes and enumerators to ensure though that format strings are largely similar. More here.

Coltin answered 9/5, 2012 at 8:32 Comment(0)
B
0

Yes, it is possible - it can be completely customized. Look at this on date and time custom formatting.

If you have your own object, it is up to you to override ToString() method and output whatever you think is appropriate representation. Once you do this, you can use String.Format("{0:MyCustomFormat}", new MyOwnClass()) because this implicitly calls MyOwnClass.ToString()

Burden answered 9/5, 2012 at 8:24 Comment(3)
-1 - The OP is asking about more than DateTime formatting. And just a link is not an answer.Venitavenite
Very harsh. DateTime is one of the aspects and I was expanding my answer while you downvoted.Burden
Expand the answer then post, and you will not get downvoted.Venitavenite
C
0

The documentation for dates can be found here: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

That should tell you exactly what all of the date formatting characters like MM mean.

If you want to change how a string is output for a custom class, you can override the ToString method, like this:

public class User
{
     public string Name { get; set; }
     public int Age { get; set; }

     public override string ToString()
     {
         return this.Name + " is " + this.Age + " years old.";
     }
}

and then you can just do something like myUser.ToString() and get the output you specified.

Cordite answered 9/5, 2012 at 8:26 Comment(0)
R
0

And to answer your third question: That's not possible with this syntax, but you can provide instances of IFormatProvider and ICustomFormatter for a type you didn't create, or implement IFormattable inside your type (although, that basically extends ToString).

Rhodarhodamine answered 9/5, 2012 at 8:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.