16

我有几个定义 DebuggerDisplay 属性的类。我想知道是否有一种方法可以基于另一个属性定义一个 DebuggerDisplay 属性。如果我有以下课程:

[DebuggerDisplay ("Text = {Text}")]
class A
{
    public string Text {get;set;}
}

[DebuggerDisplay ("Property = {Property}")]
class B
{
    public A Property {get; set;}
}

我想在 B 的实例上看到 A 类,因为它是在 A 类 DebuggerDisplay 属性上定义的。取而代之的是,我在查看 B 类对象时将 A 类 ToString() 方法放到调试器上。

4

3 回答 3

6

不确定我是否正确理解了您的问题,但请尝试:

[DebuggerDisplay("Property = {Property.Text}")]
public class B
{
    public A Property { get; set; }
}

这将显示 A 的 Text 属性。

如果您需要更复杂的控制,您可以使用DebuggerTypeProxyAttribute

于 2011-12-30T09:33:09.813 回答
2

来自https://blogs.msdn.microsoft.com/jaredpar/2011/03/18/debuggerdisplay-attribute-best-practices/(我添加了条件编译指令)

#if DEBUG
    [DebuggerDisplay("{DebuggerDisplay}")]
    public sealed class Student {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    private string DebuggerDisplay {
        get { return string.Format("Student: {0} {1}", FirstName, LastName);}
    }
}
#endif

这类似于Mickey Perlstein 的回答(清除格式化调试器字符串的属性),无需覆盖 ToString() (毕竟可能需要用于其他目的。)

源代码还为 DebuggerDisplay 提供了许多其他好的提示,包括一些性能注意事项。

编辑


由于无论如何这是调试代码,因此违反 OOP(从外部访问私有财产)并没有那么糟糕……但是我们在这里很难违反它。

private string DebuggerString {
    get {
        StringBuilder sb = new StringBuilder();
        sb.Append("Whatever you want your Parent class' Debugger Text To Say");

        var properties = typeof(GroupQuote).GetProperties()
            //get the properties with the DebuggerDisplay attribute and our property
            .Where(x =  > x.PropertyType.IsDefined(typeof(DebuggerDisplayAttribute))
                     && x.PropertyType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).Any(y =  > y.Name == "DebuggerString"));

        foreach(PropertyInfo property in properties) {
            object itemWithProperty = property.GetValue(this);
        //we have to check our property for null, otherwise trying to get its DebuggerString property will throw an exception
        if (itemWithProperty != null) {
                PropertyInfo privateDebuggerProperty = property.PropertyType.GetProperty("DebuggerString", BindingFlags.NonPublic | BindingFlags.Instance);
                sb.Append(privateDebuggerProperty.GetValue(itemWithProperty)as string);
            }
        }
        return sb.ToString();
    }
}

例子

在我编写和测试的代码中,我的 Parent 类的一些属性显示 DebuggerDisplay 是在未定义时定义的(可能是继承的东西?)。我添加了一个额外的检查,以便我们只在实际拥有它的属性上查找 DebuggerString。

于 2016-03-02T20:15:18.313 回答
1

我知道这不是“正确的编码”,但由于我不能链接我的实体,我决定回到旧的方式。只需覆盖 ToString() 方法。那么链接就是小菜一碟。

    public partial class Tld
{
    public override string ToString()
    {
        return this.Name;
    }    
}

public partial class Domain
{
    public override string ToString()
    {
        return this.DomainName + "." +this.Tld.ToString();
    } 

    public  Domain (string domain, string tld):this( domain, new Tld(tld))
    {

    }
    public Domain(string domain, Tld tld):this()
    {
        this.DomainName = domain;
        this.Tld = tld;

    }
}


public partial class Url
{
    public override string ToString()
    {
        return this.Scheme + "://" + this.Subdomain + this.Domain.ToString() + ((string.IsNullOrWhiteSpace(this.Path)) ? "" :  this.Path);
    }
    public Url (string scheme, string subdomain, string domain, string tld, string path):this(new Tld(tld),domain, subdomain,scheme,path){}

    public Url(Tld tld, string domainName, string subdomain, string scheme, string path): this(new Domain(domainName, tld),subdomain,scheme,path){}

     public Url(Domain domain, string subdomain, string scheme, string path):this()
    {
        this.Domain = domain;
        this.Path = path;
        this.Scheme = scheme;
        this.Subdomain = subdomain;

    }

}


public void Domain_Create_GOOD()
    {
     Domain expected = new Domain("google","co.nz");

    }
于 2012-06-27T16:55:03.487 回答