0

一个理论问题..我在课堂上有一个虚拟财产。另一个扩展该类的类,即使重写了虚拟属性,似乎也从未真正重写基属性的 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();
    }
}

我想,我得到了答案。

4

3 回答 3

1

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

于 2013-10-16T08:29:24.927 回答
1

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

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();
        }
    }
}
于 2013-10-16T08:34:54.493 回答
0

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

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

设置属性后调用此方法。

你会看到bla=null并且bla2="Something"

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

于 2013-10-16T08:31:29.863 回答