Formatting Strings in .NET

in utopian-io •  7 years ago  (edited)

The .NET Framework has a rich group of classes and methods for converting individual types to string representation, and for building formatted output strings.

The ToString Method

The Object class defines an overrideable method, ToString, whose purpose is to create a string representation of the value contained in the object. The default implementation simply outputs the object type. For example, the output from this code snippet would be "System.Object":

[C#]

System.Object o = new System.Object();
Console.WriteLine(o.ToString());

[Visual Basic]

Dim o As New System.Object
Console.WriteLine(o.ToString())

If a class does not override ToString, the default behavior is to output that class's type.System.ArrayList.ToString, for example, returns "System.ArrayList."

All classes can override ToString to create their own string representation. The implementation ofSystem.Decimal.ToString, for example, creates a string representation of the numeric value held by that instance.

Some classes implement overloaded versions of ToString that format the value based on parameters passed to the method. System.DateTime, for example, has four overloaded versions of the ToString method. The default, called without parameters, returns the date formatted as specified by the current culture information. Other overloads allow you to specify the culture to use and also the specific date format. System.DateTimehas several built-in formats, and you can specify custom formats as well. 

ToString doesn't have to be limited to creating a string representation of just one value. If you have a class that has several member fields, you can create a ToString method that outputs all of the fields' names and values, with one field on each line. This can come in very handy during debugging if you want to see "inside" an object. It's especially useful if you want to output the object to the trace log. The ToString method in the class shown below outputs two field names and their corresponding values.

[C#]

class MyThing
{
 private string stockNumber;
 private decimal unitPrice;

 public override string ToString()
 {
   return "stockNumber: " + stockNumber + Environment.NewLine +
     "unitPrice: " + unitPrice.ToString();
 }
}

[Visual Basic]

Class MyThing
 Private stockNumber As String
 Private unitPrice As Decimal

 Public Overrides Function ToString() As String
   Return "stockNumber: " & stockNumber & Environment.NewLine & _
     "unitPrice: " & unitPrice.ToString()
 End Function
End Class

When you're working with an unfamiliar class, it's always a good idea to examine the ToString methods that it supports. Class developers often put a lot of effort into ToString, and you just might find that the class already supports the output format that you need.

Formatting with String.Format

The .NET Framework String class provides a Format method for general purpose string formatting. With a single call to String.Format, you can create a very complex formatted string. For example, you could rewrite the ToString method in the code sample above with this call to String.Format:

[C#]

return string.Format("stockNumber: {0}\nunitPrice: {1}", stockNumber, unitPrice);

[Visual Basic]

Return String.Format("stockNumber: {0}" & Environment.NewLine & "nunitPrice: {1}", stockNumber, unitPrice)

String.Format works by replacing the format items in the first parameter (the format string) with the text equivalent of the referenced parameters. In the example above, for instance, the format items are the {0}and {1} expressions in the format string. When the code is executed, String.Format parses the format string, replaces {0} with the string representation of the passed stockNumber value, and replaces {1} with the string representation of the passed unitPrice value.

Note here that the code passes unitPrice to the method, rather than the value returned by unitPrice.ToString(). The code for string.Format will call ToString if necessary in order to obtain the string representation of a value.

There are several overloads of String.Format: special cases of one, two, and three objects to be formatted. There's also a general-purpose method that takes an array of objects. If you need to format more than three objects in a single call to String.Format, you need to put them into an array, like this:

[C#]

return string.Format("{0}, {1}, {2}, {3}",
 new object[]{obj1, obj2, obj3, obj4});

[Visual Basic]

Return String.Format("{0}, {1}, {2}, {3}", _
 New Object(){obj1, obj2, obj3, obj4});

One very cool feature of String.Format is that you can reference the format items in any order. In most cases, of course, you'll write the expressions similar to those above: references in order, followed by the parameters in the same order. However, sometimes you might need to reference a parameter more than once, or maintenance code changes require that you reverse the order of references. That's all possible withString.Format without changing the order of object parameters. For example, this C# statement outputs the parameters in reverse order:

return string.Format("{3}, {2}, {1}, {0}",
 new object[]{obj1, obj2, obj3, obj4});

You can go far with just the basic formatting that I described above. But String.Format lets you go further and specify the alignment and formatting of individual format items.

Specifying individual item formats

If you want to format a string so that fields have specific widths or alignment, you specify those in the format item. The full definition of a format item is:{index,[alignment][:formatString]}, whereindex is an integer that indicates which element in a list of objects to format. In the examples above, the format specifiers included only the index. The index is required in all format specifiers.

alignment is an optional integer indicating the minimum width of the region that will hold the formatted value. If the length of the formatted value is less than the alignment value, then the region is padded with spaces. If alignment is negative, the formatted value is left justified. If alignment is positive, the formatted value is right justified. The comma is required if alignment is specified. If alignment is not specified, the width of the region is the same as the length of the formatted value.

formatString is an optional string of formatting codes. If formatString is not specified, the default formatting for the object type is used. Otherwise, the formatString is used as a parameter to the ToString method for the object being formatted.

Format documentation topic.Format specifiers really aren't as complicated as the above description makes them sound. For example, if you want to output two numbers in columns that are 10 characters wide, you would write:

string s = string.Format("{0,10}{1,10}", 222.37, 33.48);
Console.WriteLine(s);

If you want to left-justify the numbers, make the alignment negative, like this:

string s = string.Format("{0,10}{1,10}", 222.37, 33.48);

The formatString part of the format item is used for generating alternate string representations of an item. For example, the System.DateTime type can output in many different formats. If you write this:

string s = string.Format("{0}", DateTime.Now);

The output string would be in this format:07/01/2018 9:32:26 AM

However, suppose you wanted a different format for the date. That's where formatString comes in. You can specify any format that the DateTime.ToString method supports. For example, to output in this format:Sunday, January 01, 2018 09:32:26 AM

You would write:

string s = string.Format("{0:F}", DateTime.Now);

The formatString argument is type-dependent. Valid values depend on the format strings supported by the ToString method of the type being formatted. 



Posted on Utopian.io - Rewarding Open Source Contributors

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Thank you for the contribution. It has been approved.

You can contact us on Discord.
[utopian-moderator]

Hey @yissakhar I am @utopian-io. I have just upvoted you!

Achievements

  • You have less than 500 followers. Just gave you a gift to help you succeed!
  • This is your first accepted contribution here in Utopian. Welcome!

Suggestions

  • Contribute more often to get higher and higher rewards. I wish to see you often!
  • Work on your followers to increase the votes/rewards. I follow what humans do and my vote is mainly based on that. Good luck!

Get Noticed!

  • Did you know project owners can manually vote with their own voting power or by voting power delegated to their projects? Ask the project owner to review your contributions!

Community-Driven Witness!

I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!

mooncryption-utopian-witness-gif

Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x

Good work! A link to all the string format specifiers might help for other people who read this post.

Also, you can use string interpolation since C# 6.0. It has much clearer syntax, e.g.:

var stockNumber = 3;
var unitPrice = 12.34;
Console.WriteLine("stockNumber: {stockNumber:D4}, unitPrice: {unitPrice:C}")
// outputs: stockNumber: 0003, unitPrice: $12.34