7

我有许多用 DebuggerDisplayAttribute 装饰的类。

我希望能够将跟踪语句添加到将显示这些类的实例的单元测试中。

.NET Framework 中是否存在将显示使用 DebuggerDisplayAttribute 格式化的对象的方法(如果未定义 DebuggerDisplayAttribute,则回退到使用 .ToString())?

编辑

澄清一下,我希望框架中可能包含一些内容。我知道我可以从 DebuggerDisplayAttribute 获取 Value 属性,但是我需要使用 DebuggerDisplayAttribute.Value 表示的格式字符串来格式化我的实例。

如果我自己动手,我会设想一种扩展方法,如下所示:

public string FormatDebugDisplay(this object value)
{
    DebugDisplayAttribute attribute = ... get the attribute for value ...
    if (attribute = null) return value.ToString();

    string formatString = attribute.Value;

    ??? How do I format value using formatString ???
    return SomeFormatMethod(formatString, value);
}
4

3 回答 3

3

这可能很好——但是 DebuggerDisplayAttribute 的格式字符串由调试器评估,它评估您在 Watch 窗口或 Immediate 窗口中键入的表达式的方式相同。这就是为什么您可以在大括号内放置任意表达式,例如{FirstName + " " + LastName}.

因此,要在您的代码中评估这些,您需要将 Visual Studio 调试器嵌入到您的应用程序中。应该不会发生吧 (咧嘴笑)

您最好的选择可能是采用当前在您的 DebuggerDisplay 格式字符串中的所有格式化逻辑,并将其改为方法。然后,您可以自由地从您的代码中调用该方法。您的 DebuggerDisplay 属性最终只会调用该方法。

[DebuggerDisplay("{Inspect()}")]
public class MyClass {
    public string Inspect() { ... }
}
于 2010-08-24T16:38:03.757 回答
2

此方法不会完全实现 DebuggerDisplayAttribute 在调试器中提供的内容,但这是我在代码中一直使用的。它涵盖了我们在代码库中遇到的大约 90%(或更多)的案例。如果您修复它以涵盖更多案例,我很乐意看到您的改进!

    public static string ToDebuggerString(this object @this)
    {
        var display = @this.GetType().GetCustomAttributes(typeof (DebuggerDisplayAttribute),false).FirstOrDefault() as DebuggerDisplayAttribute;
        if (display == null)
            return @this.ToString();

        var format = display.Value;
        var builder = new StringBuilder();
        for (var index = 0; index < format.Length; index++)
        {
            if (format[index] == '{')
            {
                var close = format.IndexOf('}', index);
                if (close > index)
                {
                    index++;
                    var name = format.Substring(index, close - index);
                    var property = @this.GetType().GetProperty(name);
                    if (property != null)
                    {
                        var value = property.GetValue(@this, null).ToString();
                        builder.Append(value);
                        index += name.Length;
                    }
                }
            }
            else
                builder.Append(format[index]);
        }
        return builder.ToString();
    }
于 2015-10-30T21:04:11.380 回答
1

DebuggerDisplayAttribute 有一个Value属性,它返回你想要的。

所以你可能会使用这样的东西:

var attribute = obj.GetType().
    GetCustomAttributes(typeof(DebuggerDisplayAttribute), false);
return (attribute == null) ? obj.ToString() : attribute.Value;

您甚至可以将其放入扩展方法中:

public static string ToDebugString(this object obj)
{
    var attribute = obj.GetType().
        GetCustomAttributes(typeof(DebuggerDisplayAttribute), false);
    return (attribute == null) ? obj.ToString() : attribute.Value;
}

您可以在每个对象上调用它:myObject.ToDebugString()

于 2010-05-08T12:10:50.227 回答