【问题标题】:debuggerdisplay doesn't display field value as expected调试器显示未按预期显示字段值
【发布时间】:2018-05-09 09:30:52
【问题描述】:
public class A
{
    [DebuggerDisplay("{DDBpp1()}")]
    public byte[] Bpp = new byte[2];

    public string DDBpp1()
    {
        return "DDBpp";
    }

    public string DDBpp2()
    {
        short result;

        if (BitConverter.IsLittleEndian)
        {
            var bppCopy = new byte[2];
            Bpp.CopyTo(bppCopy, 0);
            Array.Reverse(bppCopy);
            result = BitConverter.ToInt16(bppCopy, 0);
        }
        else
        {
            result = BitConverter.ToInt16(Bpp, 0);
        }

        return result.ToString();
    }
}

DebuggerDisplay 属性(DDBpp1 或 DDBpp2)中使用哪种方法并不重要。调试器下的值列始终由 {byte[2]} 填充。我期望 DDBpp1() 方法的字符串“DDBpp”或 DDBpp2() 方法的短值。 该问题出现在 VS15/17 社区下。

是否可以在调试器下更改显示字段值?

【问题讨论】:

  • 正如答案中已经解释的那样,该属性应该归类。如果您需要它的成员,那么您的成员应该是一个类本身。事实上,如果数据太复杂而无法显示,那么您的班级可能自己做的工作太多。

标签: c# visual-studio-2015 visual-studio-2017 field debuggerdisplay


【解决方案1】:

如果您将[DebuggerDisplay("{DDBpp2()}")] 放在类本身上,它将在调试器中显示bytes[] 移位的 int16 内容 - 用于类:

如果您将Bpp 实现为成员或属性并没有什么区别,并且给它更多属性也无济于事。

    [DebuggerDisplay("{DDBpp2()}", Name = "{DDBpp2()}", TargetTypeName = "{DDBpp2()}", Type = "{DDBpp2()}"]
    public byte[] Bpp { get; set; } = new byte[2];

也许把它放在课堂上可以帮助你:

[DebuggerDisplay("{CDBpp2()}")]
[DebuggerDisplay("{DDBpp2()}")]
public class A
{
    [DebuggerDisplay("{DDBpp2()}", Name = "{DDBpp2()}", TargetTypeName = "{DDBpp2()}", Type = "{DDBpp2()}")]
    public byte[] Bpp { get; set; } = new byte[2] { 255, 255 };

    public byte[] Cpp { get; set; } = new byte[2] { 11, 28 };

    public string CDBpp2() => ToDebugStr(Cpp);

    public string DDBpp2() => ToDebugStr(Bpp);

    string ToDebugStr(byte[] b)
    {
        short result;
        if (BitConverter.IsLittleEndian)
        {
            var bppCopy = new byte[2];
            b.CopyTo(bppCopy, 0);
            Array.Reverse(bppCopy);
            result = BitConverter.ToInt16(bppCopy, 0);
        }
        else
        {
            result = BitConverter.ToInt16(b, 0);
        }
        return result.ToString();
    }
}

如果您仔细查看 msdn 文档中的给定示例,您会发现该属性仅适用于类级别 - 但我很困惑,为什么他们当时没有将属性限制为类。

我看了source of debuggerDisplayAttribute.cs - 它适用于更多类,甚至可以多次使用。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Assembly, AllowMultiple = true)]

我的猜测会是 VS 没有在成员/属性/等上实现所有可能的结果。对于 IDE,这就是它不起作用的原因。如果您多次提供该属性,则在调试器视图中仅使用第一个:请参阅我的示例并对其进行调试。

【讨论】:

  • 感谢您的建议!不幸的是,您的解决方案没有解决我的问题:(,因为我有很多其他字段,所以我无法在类级别显示它们。我的解决方法是创建属性 DDBpp { get { (...) return result; } } 然后滚动到该属性而不是字段(在调试期间)。
  • @ael 您可以使用 VS 中的“发送反馈”来抱怨/报告问题 - 也许它会在 17.9.99 左右得到修复。如果没有很多道具,您可以通过将它们全部添加到类上来将它们链接起来(将评估多个 {} 并将组合字符串显示在调试器中:[DebuggerDisplay("{CDBpp2()} {DDBpp2()} etc etc etc ")] 将它们全部输出到类中
【解决方案2】:

你检查了吗:

"如果在变量窗口中显示对象的原始结构复选框 在 Tools Options 对话框中选择,然后 DebuggerDisplay 属性被忽略”

【讨论】:

  • 在我的 VS 上检查了它,但我没有检查它,所以它应该注意属性。+1 的提示,可以为以后的访问者设置。
  • @Olaf ,我在 VS2017 下也未选中该复选框。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-19
相关资源
最近更新 更多