Q:

Why / when would it be appropriate to override ToString?

I'm studying C# and I wonder what the point and benefit of overriding ToString might be, as shown in the example below.
Could this be done in some simpler way, using a common method without the override?
public string GetToStringItemsHeadings
{
    get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}

public override string ToString()
{
    string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
    return strOut;
}

A:

I'm just going to give you the answer straight from the Framework Design Guidelines from the .NET Development Series.  
AVOID throwing exceptions from ToString
CONSIDER returning a unique string associated with the instance.
CONSIDER having the output of ToString be a valid input for any parsing methods on this type.
DO ensure that ToString has no observable side effects.
DO report security-sensitive information through an override of ToString only after demanding an appropriate permission. If the permission demand fails, return a string excluding security-sensitive information.
The Object.ToString method is intended to be used for general display and debugging purposes. The default implementation simply provides the object type name. The default implementation is not very useful, and it is recommended that the method be overridden.
DO override ToString whenever an interesting human-readable string can be returned. The default implementation is not very useful, and a custom implementation can almost always provide more value. 
DO prefer a friendly name over a unique but not readable ID.  
It is also worth mentioning as Chris Sells also explains in the guidelines that ToString is often dangerous for user interfaces. Generally my rule of thumb is to expose a property that would be used for binding information to the UI, and leave the ToString override for displaying diagnostic information to the developer. You can also decorate your type with DebuggerDisplayAttribute as well.
DO try to keep the string returned from ToString short. The debugger uses ToString to get a textual representation of an object to be shown to the developer. If the string is longer than the debugger can display, the debugging experience is hindered.
DO string formatting based on the current thread culture when returning culture-dependent information.
DO provide overload ToString(string format), or implement IFormattable, if the string return from ToString is culture-sensitive or there are various ways to format the string. For example, DateTime provides the overload and implements IFormattable. 
DO NOT return an empty string or null from ToString
I swear by these guidelines, and you should  to. I can't tell you how my code has improved just by this one guideline for ToString. The same thing goes for things like IEquatable(Of T) and IComparable(Of T). These things make your code very functional, and you won't regret taking the extra time to implement any of it.
Personally, I've never really used ToString much for user interfaces, I have always exposed a property or method of some-sort. The majority of the time you should use ToString for debugging and developer purposes. Use it to display important diagnostic information.

A:

Do you need to override ToString? No.
Can you get a string representation of your object in another way? Yes.

But by using ToString you are using a method that is common to all objects and thus other classes know about this method. For instance, whenever the .NET framework wants to convert an object to a string representation, ToString is a prime candidate (there are others, if you want to provide more elaborate formatting options).
Concretely, 
Console.WriteLine(yourObject);

would invoke yourObject.ToString().

A:

Overriding ToString() allows you to give a useful human-readable string representation of a class.
This means that the output can reveal useful information about your class. For example, if you had a Person class you might choose to have the ToString() output the person's id, their firstname, their lastname etc. This is extremely useful when debugging or logging.
With regard to your example - it is difficult to tell if your override is useful without knowing what this class is - but the implementation itself is ok.

