是否存在使用DebuggerDisplayAttribute呈现对象的方法

时间:2010-05-08 11:59:09

标签: .net debugging debuggerdisplay

我有许多用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);
}

3 个答案:

答案 0 :(得分:2)

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

因此,要在代码中评估这些内容,您需要将Visual Studio调试器嵌入到您的应用中。可能不会发生。 (GRIN)

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

[DebuggerDisplay("{Inspect()}")]
public class MyClass {
    public string Inspect() { ... }
}

答案 1 :(得分: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()

答案 2 :(得分:1)

此方法将实现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();
    }