Rob Packwood
Rob Packwood

Reputation: 3808

Is there a way to automatically override ToString() on a class?

I find it useful to override ToString() on many of the simple DTO/POCO classes I write to show some good information when hovering over instances within the debugger.

Here is one example:

  public class IdValue< T >
  {
    public IdValue( int id, T value )
    {
      Id = id;
      Value = value;
    }

    public int Id { get; private set; }
    public T Value { get; private set; }

    public override string ToString()
    {
      return string.Format( "Id: {0} Value: {1}", Id, Value );
    }
  }

Is there a way in .NET to automatically have a ToString() override that lists out public properties or is there a good convention to follow?

Upvotes: 12

Views: 4217

Answers (6)

Dallas
Dallas

Reputation: 21

You could use JSON:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace ConsoleApplication1
{
    public class IdValue<T>
    {
        public IdValue(int id, T value)
        {
            Id = id;
            Value = value;
        }

        public int Id { get; private set; }
        public T Value { get; private set; }

        public override string ToString()
        {
            return new JavaScriptSerializer().Serialize(this);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var idValue = new IdValue<string>(1, "Test");
            Console.WriteLine(idValue);
            Console.ReadKey();
        }
    }
}

Which gives this output:

{"Id":1,"Value":"Test"}

Upvotes: 2

Carlo V. Dango
Carlo V. Dango

Reputation: 13882

If you don't mind an external dependency, you could turn to a framework helping with printing all of your objects properties like StatePrinter

An example usage

class AClassWithToString
{
  string B = "hello";
  int[] C = {5,4,3,2,1};

  // Nice stuff ahead!
  static readonly StatePrinter printer = new StatePrinter();
  public override string ToString()
  {
    return printer.PrintObject(this);
  }
}

Upvotes: 1

Sean H
Sean H

Reputation: 746

Listen to the folks who are warning you about performance and/or design considerations. You're tightly binding a behavior to suit a pretty limited need, when you could decouple your needs by using an extension or decorator.

Upvotes: 0

Josh
Josh

Reputation: 69262

You could override ToString in a base class then use reflection on the instance to discover the public properties of the derived class. But this will likely introduce performance problems in other areas of your code. Additionally, because ToString is used by a lot of things (String.Format, default data binding, etc.) overriding ToString for debugging purposes will make your classes less useful in other scenarios.

Instead, you may want to use the DebuggerDisplay attribute to control how the debugger shows hover tips and info in the watch window and such. I'm pretty sure this works if you apply it to a base class. You can also create custom visualizers but that's more involved. Check out this link for more info on enhancing the debugger display experience.

Enhancing Debugging

Upvotes: 17

No Refunds No Returns
No Refunds No Returns

Reputation: 8346

here A way that it MIGHT be done in a debugger friendly way

public override string ToString()
{
     stringBuilder sb = ... your usual string output
     AppendDebug(sb);
     return sb.Tostring();
}


[Conditional("DEBUG")]
private void AppendDebug(stringBuilder sb)
{
   sb.Append( ... debug - specific info )

}

The [Conditional] attribute is the key to your question.

Upvotes: 0

Ivan G.
Ivan G.

Reputation: 5215

This is not a good design consideration. I'd advice you to extract values where you need to log them or have a helper method (you can use extension methods on System.Object).

Upvotes: 0

Related Questions