如何使用get set从继承的属性中删除set访问器

时间:2014-04-15 07:57:15

标签: c# inheritance properties

假设我有类层次结构,当创建B的实例时,通过构造函数链将数字设置为默认值。由于_number的值应该是默认值,因此必须覆盖属性Number,以便删除set访问器。 / p>

abstract Class A
{
    public int Number
    {
        get
        {
            return _number
        }
        set
        {
            _number = value;
        }
     }
 }

Class B : Class A
{
    public int Number
    {
        get
        {
            return _number
        }
     }
 }

3 个答案:

答案 0 :(得分:1)

这是不可能的,因为你想要并且有充分的理由。

你实际上打破了Liskov的替代原则。利斯科夫说

  

程序中的对象应该可以替换为它们的实例   子类型而不改变该程序的正确性

由于您的基类具有公共集,因此您的派生类也应如此。

我在Override Interface Method in another Interface中提出的几乎相同的论点都可以在这里应用

由于您可以传入需要基类的派生类,如果用户在属性上调用该集,会发生什么?

尽管新方法似乎是一种可能的解决方案,但实际上这是错误的,因为newing会隐藏基本属性并且不会覆盖它。它仍然可以访问,因为你没有隐藏设置部分(你只是隐藏了getter)。

如果您在基类中将setter设为私有,那么对于base或derived,setter将不会公开显示。但是,如果您正在使用构造函数赋值,则可以选择此选项。

答案 1 :(得分:0)

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            B b = new B(10);

            // b.Number = 10; // Error here
        }
    }

    public abstract class A
    {
        public A() { }

        public A(int number)
        {
            Number = number;
        }

        private int _number;

        public virtual int Number
        {
            get
            {
                return _number;
            }
            private set
            {
                _number = value;
            }
        }
    }

    public class B : A
    {
        public B(int number)
            : base(number) { }

        public override int Number
        {
            get
            {
                return base.Number;
            }
        }
    }
}

答案 2 :(得分:-1)

可能类似

class B : A
{
    public new int Number //NEW
    {
        get
        {
            return _number; //NUMBER IS DEFINED IN (A)
        }
     }
 }

但这有问题。

即使这可以正常工作

B b = new B(); 
b.Number = 10; //COMPILER ERROR FOR READONLY PROPERTY 

这将正确编译

A b = new B(); 
b.Number = 10; //NO ERROR