为什么派生类中重写的自动实现的属性与C#中的虚拟基类属性具有不同的值

时间:2018-03-19 16:04:51

标签: c# inheritance properties method-overriding

我有一个'基地'它具有virtual int自动实现的属性,名为' id'。

class bbase
{
    public virtual int id { get; set; }

}

当我从这个班级继承到“衍生出来的'上课,我明白了:

class Derived : bbase
{
    public override int id
    {
        get
        {
            return base.id;
        }
        set
        {
            base.id = value;
        }
    }
}

初始化基类和派生类并将值赋给基类属性后,如下所示:

bbase b2 = new bbase();
Derived d2 = new Derived();
b2.id = 6;

当我尝试从派生类输出值时,它输出' 0':

Console.WriteLine(d2.id);

我的困惑是,当我尝试使用虚拟方法的相同方法时,它工作正常。使用base.method()的派生类方法工作正常。它返回基本方法中的任何内容,但为什么不返回自动实现的属性?

class bbase 
{
    public virtual void execute() { Console.WriteLine("base.execute2"); }
}

class Derived : bbase
{
     public override void execute()
     {
         base.execute();
     }
}

5 个答案:

答案 0 :(得分:5)

两者都是两个独立的对象。所以你看到的是预期的结果。

如果您重新编写代码,以便变量b2d2指向Derived类对象,如下所示,您可以尝试模拟的内容:

Derived d2 = new Derived();
bbase b2 = d2;
b2.id = 6;

现在,如果你这样做:

Console.WriteLine(d2.id); // prints 6

您将看到上面设置的相同值。

See DEMO here.

理想情况下,我认为你不应该在属性getter和setter中以这种方式调用base,就像上面的情况一样,因为你没有对base的值做任何特殊的事情,所以不要只使用默认值导出的getset如下:

class Derived : bbase
{ 
    public override int id
    {
        get;
        set;
    }
}

现在如果您写下以下内容:

Derived d2 = new Derived();
bbase b2 = d2;
b2.id = 6;
Console.WriteLine("d2:"+d2.id);
Console.WriteLine("b2: "+b2.id);

将输出:

  

d2:6

     

b2:6

请参阅working DEMO Fiddle了解它。

答案 1 :(得分:2)

b2d2是不同的对象。你可以告诉,因为你为每个人做过new次。

如果您创建了属性static,则会看到您期望的结果。

答案 2 :(得分:1)

我认为你错过了一些基本面。

您的bbase课程定义实例级别属性" id"虚拟的。这意味着可以被覆盖:

class bbase
{
    public virtual int id { get; set; }
}

您的Derived课程会覆盖实例级别属性" id":

class Derived : bbase
{
    public override int id
    {
        get
        {
            return base.id;
        }
        set
        {
            base.id = value;
        }
    }
}

所有这些意味着Derived的任何实例都会处理" id"此重写方式的属性。

实例化对象时:

bbase b2 = new bbase();
Derived d2 = new Derived();

您正在制作每个班级的实例。这些实例的属性具有自己的值。继承不相关,因为它们是两个单独的实例。您对d2所做的任何操作都不会反映在b2中,因为它们不同。

答案 3 :(得分:0)

实际上b2d2是不同的对象。 因此,如果您设置b2.id = 6;,则d2保持为0,只要您同时设置d2.id = 6;

在虚拟方法示例中,您将返回(通过覆盖它)基本方法=> base.execute();,即使您实例化d2类,这也是您获取基本方法输出的原因。

答案 4 :(得分:0)

如果您的代码如下所示:

bbase b2 = new bbase();
bbase d2 = new bbase();
b2.id = 6;
Console.WriteLine(d2.id);

你期望结果是0吗?这是一样的差异。

将派生类分配给基类的引用时,覆盖,隐藏和其他Polymorphy只会匹配。

Derived d2 = new Derived();
d2.id = 6;
bbase b2 = d2;
Console.WriteLine(b2.id);

这种任务在任何OOP语言中都会发生很多。它是使用OOP的1/2到3/4之间。