为什么当我在监视视图中观察基类对象时,VS2017为什么向我显示派生类的成员值?

Wol*_*oth 1 c# watch class-hierarchy

我有3个类别的类别层次结构:KlasseA,KlasseB和KlasseC。KlasseC继承自KlasseB。KlasseB继承自KlasseA。

这些类中的每一个都有各自的int类型的属性A,B和C以及字段a,b和c:

public class KlasseA
{
    private int a;

    public int A { get => a; set => a = value; }
}
public class KlasseB: KlasseA
{
    private int b;

    public int B { get => b; set => b = value; }
}
public class KlasseC: KlasseB
{
    private int c;

    public int C { get => c; set => c = value; }
}
Run Code Online (Sandbox Code Playgroud)

(我省略了不必要的构造函数和检查逻辑)

现在,我可以编写以下代码:

class Program
{
    static void Main(string[] args)
    {
        KlasseA aKlasse;
        KlasseB bKlasse;
        KlasseC cKlasse;
        aKlasse = new KlasseC() { A = 4, B = 5, C = 6 };
        bKlasse = aKlasse as KlasseB;
        cKlasse = aKlasse as KlasseC;
    }

}
Run Code Online (Sandbox Code Playgroud)

当我添加aKlassebKlassecKlasse以监视窗口,所有3显示该值作为类型的KlasseC,但类型显示为"KlasseA (KlasseC)""KlasseB (KlasseC)""KlasseC"分别。

展开所有3个watch变量后,我可以在所有3个变量中看到所有3个字段和属性:

-aKlasse    {KlasseC}    KlasseA {KlasseC}
 A          4            int
 B          5            int
 C          6            int
 a          4            int
 b          5            int
 c          6            int
-bKlasse    {KlasseC}    KlasseB {KlasseC}
 A          4            int
 B          5            int
 C          6            int
 a          4            int
 b          5            int
 c          6            int
-cKlasse    {KlasseC}    KlasseC
 A          4            int
 B          5            int
 C          6            int
 a          4            int
 b          5            int
 c          6            int
Run Code Online (Sandbox Code Playgroud)

我认为这是不正确的,因为在代码中我永远无法编写

aKlasse.C = aKlasse.A;
Run Code Online (Sandbox Code Playgroud)

即使监视窗口指示aKlasse具有属性AB和C。

有人可以确认或驳斥我的假设吗?

Jon*_*eet 5

它向您显示执行时间数据-这远比仅根据编译时已知的内容向您显示要有用得多。基本上,它向您显示“变量所引用的对象”,并且代码中的对象是KlasseC,而不管变量的类型如何。

例如,如果您有一个类型为type的变量Stream,但实际上MemoryStream在执行时对a的引用,那么您希望能够轻松地查看列表,而无需使用监视窗口调用Readetc。

这不是错误-这是一个功能。

  • @WolfgangRoth:调试器的目的是为您提供更多信息。如果您具有类型为object的变量,那么更有用-仅*知道该值是否为null或查看*实际数据*?请注意,调试器还可以让您查看私有字段等...所有这些在“调试时很有用”。您将无法直接从其他类访问该数据的事实并不能阻止其有用。 (2认同)