【问题标题】:Why does an overridden virtual property always point to the base class's getter and setter methods of the property为什么重写的虚属性总是指向属性的基类getter和setter方法
【发布时间】:2013-10-16 08:20:56
【问题描述】:

一个理论问题.. 我在课堂上有一个虚拟财产。另一个扩展该类的类,即使重写了虚拟属性,似乎也从未真正重写基属性的 getter 或 setter 方法。我错过了什么?

class BaseClass
{
    protected string bla;

    public virtual string Bla
    {
        get { return this.bla; }
        set { this.bla = value; }
    }

    protected BaseClass() { } 

    public BaseClass(string _bla)
    {
        this.Bla = _bla;
    }
}

class ChildClass : BaseClass
{
    private string bla2;

    public override string Bla
    {
        get
        {
            return bla2;
        }
        set
        {
            bla2 = value;
        }
    }

    public ChildClass(string _bla2) : base("AAA")
    {
        this.Bla = _bla2;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var c = new ChildClass("Me");

        Console.WriteLine(c.Bla);

        Console.ReadLine();
    }
}

我想,我得到了答案。

【问题讨论】:

  • 该代码无法编译。如果基类的属性设置器受到保护,则不能将派生类的 Bla 属性设置器设为公开。 ChildClass 也没有默认构造函数,所以 var c = new ChildClass(); 无法编译。
  • @VenkatRenukaPrasad 您的代码不起作用。覆盖受保护的继承成员时,您无法更改访问修改。
  • 同样不存在无参数的ChildClass构造函数。
  • 修复了“受保护”问题,我的结果很好。无论我将 c 声明为 var 还是 ChildClass。

标签: c# properties overriding virtual


【解决方案1】:

如果您修复代码以使其能够编译,它会按预期工作。但是,请注意我添加的 cmets!您正在从构造函数调用虚拟方法(属性设置器,但仍然是方法)。这很糟糕。

using System;

namespace Demo
{
    class BaseClass
    {
        protected string bla;

        public virtual string Bla
        {
            get
            {
                return this.bla;
            }
            set
            {
                this.bla = value;
            }
        }

        protected BaseClass()
        {
        }

        public BaseClass(string _bla)
        {
            this.Bla = _bla;
        }
    }

    class ChildClass: BaseClass
    {
        private string bla2;

        public override string Bla
        {
            get
            {
                return bla2;
            }
            set
            {
                bla2 = value;
            }
        }

        public ChildClass(string _bla2)
            : base("AAA")
        {
            // Step into the next line of code in the debugger.
            // You'll see that it goes into the ChildClass.Bla setter.
            // However note that this is making a virtual call in a constructor 
            // - which is very bad if there is a further derived class because
            // it will call a method in that derived class before that derived
            // class has been constructed.
            // You can fix this potential problem by making this entire class
            // sealed or by making the property sealed in this class.

            this.Bla = _bla2; 
        }
    }

    class Program
    {
        private void run()
        {
            var c = new ChildClass("X");

        }

        static void Main(string[] args)
        {
            new Program().run();
        }
    }
}

【讨论】:

    【解决方案2】:

    base("AAA") 调用 public BaseClass(string _bla) { this.Bla = _bla; }this.Bla 的值(在子类中它指向字段 bla2)设置为“AAA”,因此在 public ChildClass(string _bla2) { this.Bla = _bla2; } this.Blabla2 中已经通过基本构造函数分配。

    【讨论】:

      【解决方案3】:

      我对您的代码进行了单元测试,它可以工作,添加子类:

          public override string ToString()
          {
              return string.Format("bla = {0},bla2 ={1}", bla,bla2);
          }
      

      设置属性后调用该方法

      你会看到bla=nullbla2="Something"

      编辑 正如评论中所说,我不得不将设置器的可见性级别更改为公共,删除子类中的构造函数

      【讨论】:

        猜你喜欢
        • 2011-10-05
        • 1970-01-01
        • 1970-01-01
        • 2010-09-24
        • 2021-08-08
        • 2012-09-16
        • 2019-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多