Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 链接调试程序在复杂类型上显示_C#_.net_Debuggerdisplay - Fatal编程技术网

C# 链接调试程序在复杂类型上显示

C# 链接调试程序在复杂类型上显示,c#,.net,debuggerdisplay,C#,.net,Debuggerdisplay,我有几个类定义了DebuggerDisplay属性。我想知道是否有一种方法可以基于另一个DebuggerDisplay属性定义一个DebuggerDisplay属性。如果我有以下课程: [DebuggerDisplay ("Text = {Text}")] class A { public string Text {get;set;} } [DebuggerDisplay ("Property = {Property}")] class B { public A Propert

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

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

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

我希望看到在类A DebuggerDisplay属性上定义的类B的实例。相反,我在查看B类对象时将类A ToString()方法放到调试器上。

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

[DebuggerDisplay("Property = {Property.Text}")]
public class B
{
    public A Property { get; set; }
}
这将显示A的文本属性

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

我知道这不是“正确的编码”,但由于我无法链接我的实体,我决定回到旧方法。只需重写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");

    }
From(我添加了条件编译指令)

这类似于answer(设置调试器字符串格式的clear属性),而不需要重写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();
    }
}


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

如果(在这种情况下)类A有几个属性,该怎么办。必须将A DebuggerDisplay属性重写到类B中对我来说是个糟糕的选择。[DebuggerDisplay]只适用于简单的情况。很明显,你的目标是[DebuggerTypeProxy]。相关:这不是一个坏主意,但主要的问题是,促使我创建这篇文章的那个问题仍然没有答案。如果属性是具有已定义DebuggerDisplay的对象,则我无法使用已定义的属性表示它们(除非我将DebuggerDisplay属性设置为公共)。您可以使用反射(并且完全不尊重OOP原则)来检索私有属性。我用一个基本的例子编辑了我的答案。这一点很好,但我实际上认为仅仅为了显示一些调试信息,这有点过头了。关键是:调试器知道类型具有DebuggerDisplay属性,因此如果它找到指向已定义属性的对象的DebuggerDiplay,请使用它!所以我不是100%了解DebuggerDisplayAttribute是如何工作的,但是看看它的反编译代码,它看起来只是存储了你给它的字符串,例如:“{aProperty}”,我认为调试器本身会解释该字符串来检索值,在属性本身中没有花哨的代码。因此,尽管调试器确实检查父对象是否具有该属性(以显示它而不是ToString()),但如果不以我的粗糙反射的方式进行查看,它将不知道父对象的任何属性是否也具有该属性。
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();
    }
}