42

I like the DebuggerDisplay attribute. I like it so much, that I want to use it on types that I don't have the source code for.

Is this possible?

Steve Dunn
  • 21,044
  • 11
  • 62
  • 87
  • Some hope that DebuggerTypeProxy at the assembly level might work. It didn't. – Hans Passant Dec 17 '10 at 13:20
  • @Hans Passant - Haven't tried it myself, but this article http://blog.jalil.org/2008/02/18/how-to-determine-event-subscribers/ shows an example of using DebuggerTypeProxy directed at a foreign assembly. – Omer Raviv Dec 20 '10 at 09:10

3 Answers3

43

Example of setting DebuggerDisplay for a foreign type (System.Collections.Generic.KeyValuePair<TKey,TValue>) add the following to AssemblyInfo.cs:

using System.Collections.Generic;
using System.Diagnostics;

[assembly: DebuggerDisplay("[Key={Key}, Value={Value}]", Target = typeof(KeyValuePair<,>))]

(Tested in VS2015)


Edit 2020:

Was not able to reproduce the above for KeyValuePair<,> in VS2019 but it seems to be related to KeyValuePair<,>.

For private member of non owned types try something like this

ClassLibrary1:

//using System.Diagnostics;

namespace ClassLibrary1
{
    //[DebuggerDisplay("Foo.Bar={Bar}")] // works too for types you own
    public class Foo
    {
        private int Bar = 42;
    }
}

ConsoleApp1:

using System.Diagnostics;
using System.Reflection;
using ClassLibrary1;

[assembly: DebuggerDisplay("Foo.Bar={FooDebuggerDisplay.Bar(this)}", Target=typeof(Foo))]

class FooDebuggerDisplay
{
    public static int Bar(Foo foo) => (int)foo.GetType().GetField("Bar",BindingFlags.Instance|BindingFlags.NonPublic).GetValue(foo);
}

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var foo = new Foo();
            Debugger.Break();
        }
    }
}

(Tested in VS2019)

Jens
  • 2,327
  • 25
  • 34
22

Yes. In fact, Microsoft was so nice as to make this a built-in option in Visual Studio.

Look up the "My Documents\Visual Studio 20XX\autoexp.cs" for some examples of how you apply the DebuggerDisplay attribute to types that are foreign to your assembly. Then, add some of your own, recompile it and replace the autoexp.dll, and restart Visual Studio. It should Just Work.

For reference, see the yellow "Note" paragraph in this MSDN article


Alternatively: I'm the creator of a purchasable extension to Visual Studio that enables doing this with a lot less fuss, without even needing to have to stop the debugging session.

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Omer Raviv
  • 11,409
  • 5
  • 43
  • 82
  • Nice answer - I tried the autoexp solution - the third party code I want to change debugger display is inside entity framework. the compilation of autoexp failed since I did not include it. Do you have any tips if I can/I should include other third party libraries in compilation? – user3141326 Mar 12 '16 at 14:21
  • I found it you can see the full instructions in here: http://www.tech-archive.net/Archive/VisualStudio/microsoft.public.vsnet.debugging/2006-08/msg00038.html it works without any issues. There is no need to restart visual studio. Just hitting F5 after compiling autoexp.dll is enough. Thanks for the great answer. – user3141326 Mar 12 '16 at 14:39
  • In VS2015 still possible but autoexp.cs is not present see: https://stackoverflow.com/questions/33394892/modifying-external-debuggerdisplay-with-autoexp-cs-in-visual-studio-2015 – IvanH Feb 19 '18 at 14:38
1

Attributes are a way to decorate something (types, methods, fields, etc) at compile time and they are stored in the binary representation of an assembly. One way to add a new attribute in it is to recompile the code with the new attribute. If you don't have the code, in some cases, you might get the code by decompiling the assembly.

Another way I can think of, might be to use Reflection to load and process all the types in an assembly and then generate (through reflection) another assembly with DebuggerDisplay added to the types you want (here's an example)

Andrei Pana
  • 4,484
  • 1
  • 26
  • 27