9

The Attribute [DebuggerDisplay] (Using DebuggerDisplayAttribute) allows to define the display in the Debugger of VS 2010/2008. By modifying AutoExp.cs/.dll, I can even override the display of system types and 3rd party types, e.g.

[assembly: DebuggerDisplay (@"\{Name = {Name} FullName = {FullName}}", Target = typeof (Type))]

In the inner curly braces I can reference fields, properties and methods. Is it possible to reference extension methods ?

As an example, I tried to display shorter type names, e.g. $SCG.Dictionary instead of System.Collections.Generic.Dictionary. I added this to AutoExp.cs:

using DbgDisp;

[assembly: DebuggerDisplay (@"\{Name = {Name} ShortName = {ShortName()}}", Target = typeof (Type))]

namespace DbgDisp {
  public static class Ext {
    public static string ShortName (this Type t) { return string.Format ("[{0}]", t.Name); }
  } // Ext
} // DbgDisp

but the debugger complains: The name 'ShortName' does not exist in the current context.

Am I missing something, or is it just not possible to use extension methods there ?

I know I could override ToString (), but that helps only for my own types.

Community
  • 1
  • 1
MillKa
  • 413
  • 4
  • 10
  • Of course, some smart other way to execute my own code in the debug display context would be interesting, too :) – MillKa Apr 09 '11 at 10:04
  • This helped me create a custom display string for debugging. Was possible using an extention for a sealed class. seesharpers answer should be marked as accepted answer per site policy here: http://meta.stackexchange.com/questions/62252/is-it-poor-form-to-switch-accepted-answers – Taterhead Nov 02 '16 at 15:51

3 Answers3

12

Actually you can use extension methods passing this as the argument

[assembly: DebuggerDisplay(@"NetGuid = {ToString()} OracleGuid = {GuidExtensions.ToVarChar(this)}", Target = typeof(Guid))]
public static class GuidExtensions
{
    public static string ToVarChar(this Guid guid)
    {
        var newBytes = new byte[16];
        var oldBytes = guid.ToByteArray();
        for (var i = 8; i < 16; i++)
            newBytes[i] = oldBytes[i];

        newBytes[3] = oldBytes[0];
        newBytes[2] = oldBytes[1];
        newBytes[1] = oldBytes[2];
        newBytes[0] = oldBytes[3];
        newBytes[5] = oldBytes[4];
        newBytes[4] = oldBytes[5];
        newBytes[6] = oldBytes[7];
        newBytes[7] = oldBytes[6];

        return new Guid(newBytes).ToString("N").ToUpper();
    }    
}
seesharper
  • 3,249
  • 1
  • 19
  • 23
  • 2
    Thanks very much, this works perfectly (in VS2017 at least). Note to others: your `[assembly:` attribute is not defined within any namespace, so you must fully specify the namespace of the type. i.e. `MyCompany.MyProduct.Utils.GuidExtensions.ToVarChar(this)` – Drew Noakes Oct 27 '18 at 22:30
  • Awesome, I needed to add DebuggerDisplay to a generated class and thought it impossible until I came across your answer. [assembly: DebuggerDisplay ... ] did the trick. – Steve Crane Jun 14 '22 at 08:09
5

In short, no. For the same reasons that extension methods don't work with dynamic, which is that from just the method name, there is no way of knowing what using directives were in effect, and hence which extension methods are candidates. It is entirely possible to have scenarios where using different using directives changes the available methods, so there is no benefit in having it try to guess.

You'll have to limit yourself to regular methods, unless the string allows you to specify static methods on classes explicitly, i.e. DbgDisp.Ext.ShortName(foo).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks, Marc. Nope, explicit method name `DbgDisp.Ext.ShortName` doesnt work either. I thought it was smart to sneak into the type with an extension method, but when AutoExp is compiled, it just copies the string literal. I guess that later, at debug time, the string literal is evaluated and then the debugger uses reflection to find the method (`type.GetMethods ()`). If it doesnt look outside the type, it cant find my method. So i guess the context mentioned in the error message is the type itself. – MillKa Apr 09 '11 at 12:48
  • 1
    However, it is possible to add `DebuggerTypeProxy` attributes to 3rd party and system types in AutoExp, but that might be a solution to another problem :) – MillKa Apr 09 '11 at 12:48
  • This answer is not technically wrong, but it unnecessarily discourages people when there is a way to achieve what they want to do here. You _can_ define a static method on another type (extension or otherwise) and use it to provide the debugger display string for a type you don't control. You just have to fully qualify the type/method and pass `this` as the argument. See [seesharper's answer](https://stackoverflow.com/a/39905173/24874). – Drew Noakes Oct 27 '18 at 22:33
0

You could put a private method in your class that uses the extension method you want to generate the string. The DebuggerDisplay attribute can then reference that method.

RJFalconer
  • 10,890
  • 5
  • 51
  • 66
  • This assumes you can modify the target type. The original question uses the `TargetType` property of the `DebuggerDisplayAttribute`, so I assume that's not the case here. – Drew Noakes Oct 27 '18 at 22:21