派生类可以隐藏访问者 - 下面的代码有什么问题

时间:2014-02-22 06:16:35

标签: c# inheritance accessor

我试图在派生类中隐藏访问器,它有效吗?我的系统没有回复执行。

class BaseCS
  {
      private string name;

      public string Name
      {
          get { return name; }
          set { name = "Base " + value; }
      }    
  }

  class DerivedCS : BaseCS
  {
      public new string Name
      {
          set { Name = "Der " + value; }
          get { return Name; }
      }
  }

public static void Main()
        {
            BaseCS one = new DerivedCS();

            one.Name = "One";

            Console.WriteLine("Name of object one is {0} ", one.Name);


            ((BaseCS)one).Name = "On1";
            Console.WriteLine("Name of object one is {0} ", one.Name);
        }

我不应该期望输出,

Name of object one is Base Der One
Name of object one is Base On1

2 个答案:

答案 0 :(得分:2)

  1. 此代码:

    public new string Name
    {
        set { Name = "Der " + value; }
        get { return Name; }
    }
    

    会导致堆栈溢出,因为getter和setter中的Name会引用Name中的DerivedCS,而不是BaseCSName属性将永远调用自己,直到崩溃。您需要使用base.Name

  2. 你可能想要的是多态性。您应该在派生类中设置属性virtualoverride setter。

    如果您不使用虚拟属性,则以下对象将无法按您的方式运行:

    BaseCS one = new DerivedCS();
    one.Name = "name"; // base implementation is called
    
  3. 在setter中更改属性值通常是个坏主意。用户希望遵循以下合同:

    var a = new A();
    a.Foo = "bar";
    Debig.Assert(a.Foo == "bar");
    

答案 1 :(得分:0)

这是你应该做的事情

    class BaseCS
    {
        private string name;

        public virtual string Name
        {
            get { return name; }
            set { name = "Base " + value; }
        }

    }

    class DerivedCS : BaseCS
    {
        public override string Name
        {
            set { base.Name = "Der " + value; }
            get { return base.Name; }
        }
    }

或使用新关键字

 class BaseCS
    {
        private string name;

        public string Name
        {
            get { return name; }
        set { name = "Base " + value; }
    }

}

class DerivedCS : BaseCS
{
    public new  string Name
    {
        set { base.Name = "Der " + value; }
        get { return base.Name; }
    }
}

now you should create the object as the derived type to get your expected result

     DerivedCS one = new DerivedCS();