C# ToString: Get String From ObjectOverride the virtual ToString method. Get a string representation with ToString.
dot net perls
ToString. This method is virtual. It returns a string representation. We must override ToString on custom types for the method to be effective.
For numeric types, there are performance and functional differences with ToString. We test the performance of ToString with various arguments.
To start, the ToString method is a virtual method on the object type. Every type inherits from object. Thus we can use an override ToString method to change the implementation used.
Then When the ToString method is called on the instance, the override method is used. Here we override the ToString method.
Info The ToString method on the Perl instance is never called directly. It is called by the logic inside Console.WriteLine.
And The Perl instance is received as an object, and the virtual method ToString is called internally.
C# program that overrides ToString
using System; class Perl { int _a; int _b; public Perl(int a, int b) { _a = a; _b = b; } public override string ToString() { return string.Format("[{0}, {1}]", _a, _b); } } class Program { static void Main() { Perl perl = new Perl(1, 2); Console.WriteLine(perl); } }
[1, 2]
Numbers. ToString is culture-sensitive. For a Double whose value is zero, the implementation of Double.ToString might return "0.00" or "0,00" depending on the UI culture.
Next We compare ToString() with no parameters (no format string) and ToString() with the NumberFormatInfo specified.
Info In many programs, there is no culture-sensitive code. I use ToString() in many places simply to convert an integer to a string.
Also ToString() with no parameters gets the culture internally, but this may be non-optimal.
C# program that uses ToString
using System; using System.Globalization; // Important class Program { static void Main() { int a = 4000; int b = 654; double c = 453.4; double d = 50000.55555; string a1 = a.ToString(); string a2 = a.ToString(NumberFormatInfo.InvariantInfo); Console.WriteLine(a1 + " " + a2); string b1 = b.ToString(); string b2 = b.ToString(NumberFormatInfo.InvariantInfo); Console.WriteLine(b1 + " " + b2); string c1 = c.ToString(); string c2 = c.ToString(NumberFormatInfo.InvariantInfo); Console.WriteLine(c1 + " " + c2); string d1 = d.ToString(); string d2 = d.ToString(NumberFormatInfo.InvariantInfo); Console.WriteLine(d1 + " " + d2); } }
4000 4000 654 654 453.4 453.4 50000.55555 50000.55555
Optimization. The ToString method on the int type uses a property called CultureInfo to get the current culture. It sends the System.IFormatProvider to the ToString method.
Thus ToString with no parameters gets a NumberFormatInfo. I have found that property accesses like get_CurrentCulture() are slow.
Int, uint
Info A solution to this inefficiency is to pass ToString() an already-created NumberFormatInfo.
C# program that shows NumberFormat
using System; using System.Globalization; class Program { static void Main() { // This code converts the int 900 to a string. string a = 900.ToString(); Console.WriteLine(a); // This code converts the int 900 to a string. // ... Has the same exact results. NumberFormatInfo n = CultureInfo.InvariantCulture.NumberFormat; string b = 900.ToString(n); Console.WriteLine(b); } }
900 900
Optimization, continued. Here is the ToString benchmark. We test the performance of NumberFormatInfo arguments to ToString in 2 tight loops.
Version 1 Here we call ToString with no arguments. The NumberFormatInfo is accessed internally in the ToString call.
Version 2 This code eliminates the need for ToString to access a property internally. This speeds up this operation in loops.
Result Version 2 is faster for invariant cultures. This optimization may be worth testing in certain loops.
C# program that tests ToString performance
using System; using System.Diagnostics; using System.Globalization; class Program { const int _max = 1000000; static void Main() { NumberFormatInfo f = CultureInfo.InvariantCulture.NumberFormat; // Version 1: use ToString with no argument. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { string result = i.ToString(); if (result == null) { break; } } s1.Stop(); // Version 2: use ToString with NumberFormatInfo argument. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { string result = i.ToString(f); if (result == null) { break; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); } }
104.68 ns ToString() 87.84 ns ToString(f)
A discussion. When using simple integers or other value types, consider specifying the invariant culture number format. This reduces the execution time.
Notes, lookup. We can implement a cache for string representations returned by ToString. Consider using a lookup table (array or Dictionary) and store already-created strings.
A summary. We used an override method for the ToString virtual method on the object type. We looked at some aspects of the ToString method on the int type in the C# language.
© 2007-2021 sam allen. see site info on the changelog