代码之家  ›  专栏  ›  技术社区  ›  p.campbell

.NET继承:抑制基类中的属性

  •  8
  • p.campbell  · 技术社区  · 14 年前

    public class Emp
    {
        public string Name { get; set; }
        public Manager Manager { get; set; }
        public Assistant Assistant { get; set; }
    }
    
    public class Manager : Emp
    { 
    }
    
    public class Assistant : Emp
    {
    }
    

    目标是禁止一段代码访问如下属性:

    var foo = new Manager();
    var elmo = new Emp();
    elmo.Manager = foo;
    elmo.Manager.Manager = new Manager(); 
    //how to disallow access to Manager.Manager ?
    

    Manager 继承自 Emp ,它有一个 .Manager .Assistant

    问题:

    在.NET的继承实现中是否有任何修饰符可以删除 经理 财产?

    更新

    Person ,课程将共享姓名、生日等)非常感谢您的输入!

    6 回复  |  直到 14 年前
        1
  •  9
  •   recursive    14 年前

    这样做会违反法律 Liskov substitution principle ,通常是设计有问题的标志。一般来说,任何子类都应该能够在基类所属的任何上下文中使用。如果 Manager 我们没有 .Manager s、 那就不是了 Emp s、 不应该从他们那里继承。

        2
  •  5
  •   Jon Skeet    14 年前

    Liskov's Subsitution Principle . 基本上,你可以添加东西,但不能将它们拿走。

    您可能会重写该属性以在执行时抛出异常,但不能在编译时执行。

    一般来说,如果你不同意这种事情,你应该考虑组合而不是继承,因为你没有真正的继承关系。

        3
  •  2
  •   SLaks    14 年前

    您可以创建基类属性 virtual ,然后重写它以在setter中引发异常,但无法给出编译时错误。毕竟,在编译时没有什么可以防止的

    (elmo.Manager as Employee).Manager = new Manager();
    

    public class ManagerEmployee : Emp {     
        public new ManagerEmployee Manager { 
            get { return base.Manager; }
        }
    }
    

    请注意,这不会阻止铸造。

        4
  •  1
  •   3Dave    14 年前

    和大多数事情一样,这要看情况而定。鉴于以下类别:

    public class foo
    {
        public string Test { get { return "foo"; } } 
    }
    
    public class bar : foo
    {
        public new string Test { get { return "bar"; } }
    }
    

    以及以下代码:

            bar a = new bar();
            // returns bar
            literalTest1.Text = a.Test;
    
            foo b = new foo();
            // returns "foo"
            literalTest2.Text = b.Test;
    
            foo c = new bar();
            // returns "foo"
            literalTest3.Text = c.Test;
    

    根据上面的评论,您可以看到 可以

    改为修复您的祖先类。

        5
  •  0
  •   Daniel Auger    14 年前

        6
  •  0
  •   Lee    14 年前

    不,你不能这样做,你也不想这样做——要么经理是员工,有经理和助理,要么没有,因此应该有不同的基类,即这种情况表明存在设计缺陷。一种可能是为这些属性返回null,不过如果这对域有意义的话。