【问题标题】:Can the DebuggerDisplay attribute be applied to Microsoft.Office.Interop.Word.Range?可以将 DebuggerDisplay 属性应用于 Microsoft.Office.Interop.Word.Range 吗?
【发布时间】:2018-07-02 04:15:13
【问题描述】:

根据这个问题Can the DebuggerDisplay attribute be applied to types one doesn't own 提出的问题,是否可以将DebuggerDisplay 属性应用于来自外部程序集的类型?

如果是这样,有没有办法专门将其应用于Microsoft.Office.Interop.Word.Range?


我尝试了以下代码,但它不起作用:

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

在运行时调试器显示此字符串:

{System.__ComObject}

但“System.__ComObject”不可访问,因为它是“朋友”。

【问题讨论】:

  • 调试器可能无法像运行时代码那样使用用于 COM 对象的透明代理。改用DebuggerTypeProxy(即使工作量更大)
  • @JeroenMostert 你能举一个 DebuggerTypeProxy 的例子吗?
  • Sure。 (尽管有标题,但它也涵盖了DebuggerTypeProxy。)

标签: .net debugging com vsto ms-office


【解决方案1】:

但“System.__ComObject”不可访问,因为它是“朋友”。

确实如此。但是System.__ComObject 继承自公共MarshalByRefObject。如果您为它们的基类设置DebuggerDisplay 属性,它将适用于所有派生类。所以你可以将typeof(MarshalByRefObject) 设置为DebuggerDisplay 属性的目标。

如果你这样做,你不能只在格式化程序中使用{Text},因为MarshalByRefObject 没有这样的属性。为了克服这个问题,你可以定义一个简单的静态助手来检查传递的对象的类型。如果是Range,它将调用Text。否则默认为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";
    }
}

现在你可以设置DebuggerDisplay属性:

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

确保为 DisplayHelper 类指定完整的命名空间(将 FullNamespace.Goes.Here 替换为您的实际命名空间)。

这是调试器中的结果视图:

【讨论】:

    猜你喜欢
    • 2011-05-27
    • 2013-06-22
    • 2019-07-23
    • 2014-06-10
    • 2015-03-10
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多