Search code examples
.netdebuggingcomvstoms-office

Can the DebuggerDisplay attribute be applied to Microsoft.Office.Interop.Word.Range?


Depending on what is asked on this question Can the DebuggerDisplay attribute be applied to types one doesn't own, can one apply the DebuggerDisplay attribute to types from external assemblies?

If so, is there a way apply it specifically to a Microsoft.Office.Interop.Word.Range?


I tried the following code and it did not work:

<Assembly: DebuggerDisplay("text: {Text}", Target:=GetType(Word.Range))>

At a runtime Debuger displlays this string:

{System.__ComObject}

But 'System.__ComObject' is not accessible because it is 'Friend'.


Solution

  • But 'System.__ComObject' is not accessible because it is 'Friend'.

    That's true. However System.__ComObject inherits from public MarshalByRefObject. And DebuggerDisplay attribute will work for all derived classes if you set it for their base class. So you could set typeof(MarshalByRefObject) as a target for DebuggerDisplay attribute.

    If you do this, you can't just use {Text} in formatter because MarshalByRefObject does not have such property. To overcome this, you could define the simple static helper that will check what is the type of passed object. If it's a Range it will call Text on it. Otherwise it will default to obj.ToString():

    public static class DisplayHelper
    {
        public static string DisplayRange(MarshalByRefObject obj)
        {
            var range = obj as Range;
            return range?.Text ?? obj?.ToString() ?? "The value is null";
        }
    }
    

    Now you could set DebuggerDisplay attribute:

    [assembly: DebuggerDisplay("text: {FullNamespace.Here.DisplayHelper.DisplayRange(this)}"
               , Target = typeof(MarshalByRefObject))]
    

    Be sure to specify full namespace for DisplayHelper class (replace FullNamespace.Goes.Here with your actual namespace).

    Here is result view in the debugger:

    enter image description here