代码之家  ›  专栏  ›  技术社区  ›  Ogre Psalm33

如何在C#中隐藏(删除)基类的方法?[副本]

  •  17
  • Ogre Psalm33  · 技术社区  · 17 年前

    问题的本质是,给定这样的类层次结构:

    class A
    {
        protected void MethodToExpose()
        {}
    
        protected void MethodToHide(object param)
        {}
    }
    
    class B : A
    {
        new private void MethodToHide(object param)
        {}
    
        protected void NewMethodInB()
        {}
    }
    
    class C : B
    {
        public void DoSomething()
        {
            base.MethodToHide("the parameter"); // This still calls A.MethodToHide()
            base.MethodToExpose(); // This calls A.MethodToExpose(), but that's ok
            base.NewMethodInB();
        }
    }
    

    A.MethodToHide() ? 在C++中,使用声明(如 class B : private A ,但此语法在C#中无效。

    对于那些感兴趣(或想知道我在做什么)的人 我们要做的是为Rhino.Commons.NHRepository创建一个包装器,它隐藏了我们不想向我们的开发团队公开的方法,这样我们就可以用一种千篇一律的方式开发我们的应用程序,新开发人员可以很容易地遵循。因此,是的,我相信“Is-A”测试对整个链是有效的(WidgetRepository是一个BaseRepository是一个NHRepository)。

    :为了便于讨论,我应该提到类A是我们无法控制的API类。否则问题就会变得相当容易。

    10 回复  |  直到 17 年前
        1
  •  22
  •   Monkey Code    11 年前

    过时

    在类B中,重写MethodToHide并添加过时属性

    [Obsolete("Reason", true)] // true will cause a compile-time error
    

    设置EditorBrowsable

    (如前所述)

    在类B中,重写MethodToHide并添加EditorBrowsable属性

    [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
    

    抛出异常

    (如前所述)

    在类B中,重写MethodToHide并引发异常。

    创建包装器

    Adapter pattern . 这种模式还允许在单元测试时更容易地模拟代码。

    class B: IInterface
    {    
        protected void MethodToExpose()
        {
            A a = new A();
            a.MethodToExpose();
        }
    
        protected void NewMethodInB()
        {
        }
    }
    
        2
  •  21
  •   John Rasch    17 年前

    您不能这样做并保留层次结构。如果可能,您应该创建定义理想的接口,然后对基类进行子类化并实现接口。在代码中只引用接口(而不是基类类型)。

    这个 Adapter pattern

        3
  •  14
  •   Blixt    17 年前

    如果你想定制一组特性,我想说你想做一个包装器而不是继承功能。我也不知道如何在C#中实现你的愿望。

    想想看,如果你控制之外的一些代码想要这个呢 NHRepository 举个例子。。。但是您已经从子类中删除了它所需的函数(您将发送该函数,因为这是您唯一的子类) NH存储库 (举例)一切都很顺利。这就是为什么我认为没有一些丑陋的黑客是不可能的。

        4
  •  6
  •   Jake Pearson    17 年前

    如果您使用的是Visual Studio,则可以使用以下属性对intelliprompt隐藏方法/属性:

    class A
    {
        protected void MethodToExpose()
        {}
    
        [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
        protected void MethodToHide(object param)
        {}
    }
    

        5
  •  4
  •   Guy Levin    11 年前

    在我看来,如果您只是想隐藏而不是真正覆盖和外部化一个新的函数,那么最好的方法就是添加一个EditorBrowsableState属性。

    只需在方法的顶部添加以下代码:

    [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
    

    例如

    public class User
    {        
        public void DoSomething()
        {
           Something...
        }
    }
    
    public class Manager
    {
        [System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
        public override void DoSomething()
        { }
    }
    
    void main()
    {
       User user = new User();
       user.DoSomething();
    
       Manager manager = new Manager();
       manager.DoSomething(); // --------- This row will throw a design time error
    }
    

    祝你好运:)

        6
  •  1
  •   LBushkin    17 年前

    C++中没有类似于受保护或私有继承的概念。

    最好的选择是聚合类的一个实例,并公开用户有权访问的感兴趣的方法集。

    虽然在您的情况下,我认为这是不可能的,但是您可以考虑创建一个只公开您希望消费者使用的常见功能的接口,以便在某些情况下包装器可以替换为它的聚合。

        7
  •  1
  •   Frank V    17 年前

    我从来不知道你可以用C++做这件事,虽然我对C++不太了解。恐怕我同意布利克斯的说法 这可能是我实现这一点的方式。

    它可能会工作(但我不确定)只是 并在调用时抛出异常。。。。

        8
  •  1
  •   Fredrik Mörk    17 年前

    据我所知,你不能以你想要的方式隐藏它。我认为你可以阻止它以任何实际的方式被使用,尽管:

    class B : A
    {
        public new void MethodToHide(object param)
        { 
            throw new DontUseThisMethodException();
        }
    
        protected void NewMethodInB()
        {}
    }
    

    但这不是最好的办法,所以你可能想用其他方法来解决它。。。

        9
  •  1
  •   KDogg    16 年前

    实际上,如果您将B的方法定义为可从C访问,则可以对C隐藏A的方法。

    代码的唯一问题是在隐藏声明中使用了“private”。。。如果您使用protected或public,您将不会遇到任何问题,它将按照您的预期运行。我总是用字段来做这些。

        10
  •  0
  •   James    17 年前