C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Then: When the ToString method is called on the instance, the override method is used. Here we override the ToString method.
VirtualInfo: 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.
ConsoleC# 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);
    }
}
Output
[1, 2]
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);
    }
}
Output
4000 4000
654 654
453.4 453.4
50000.55555 50000.55555
Thus: ToString with no parameters gets a NumberFormatInfo. I have found that property accesses like get_CurrentCulture() are slow.
ILInt, uintInfo: 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);
    }
}
Output
900
900
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"));
    }
}
Output
104.68 ns    ToString()
 87.84 ns    ToString(f)