【问题标题】:How to hide all overrides off parent method in C#如何在 C# 中隐藏父方法的所有覆盖
【发布时间】:2012-12-27 22:34:03
【问题描述】:

我正在扩展一个库类,它有一个我不希望从外部调用的公共方法。我知道我可以使用“new”关键字来隐藏它,但问题是它有很多不同的声明。 像这样的:

class Parent() {
  public double method(double a, double b) { ... }
  public int method(int a, int b) { ... }
  public System.Int32 method(System.Int32 a, System.Int32 b) { ... }
}

现在我可以这样做了:

class Child() {  
  // Make method private.
  private new double method(double a, double b) { return base.method(a, b) }
  private new int method(int a, int b) { return base.method(a, b) }
  private new System.Int32 method(System.Int32 a, System.Int32 b) { return base.method(a, b) }

  /// Own Code.
}

但我想知道是否没有更简单的方法可以将该函数的所有覆盖设为私有。

【问题讨论】:

  • 没有。还要考虑在使用方法之前将对象(Child 类型)强制为Parent 的情况。 C# 中的继承在基本 LSP 规则下确实最有效。
  • 同意@pst。当你从Parent 派生Child 时,你必须记住Child 是一个 Parent。如果您可以在Parent 上调用该方法,那么您必须能够在Child 上调用它。
  • 你可能是对的,我都准备好害怕了。我想我仍然在脚本语言方面想得太多。谢谢。
  • 如果可能的话,您可以在子类中有一个 Parent 类型的私有成员,这样您就可以在私有父类对象上调用该方法,而无需让子类从父类继承。跨度>
  • 这不是继承的使用方式。 Child 旨在支持父级的所有功能。

标签: c# polymorphism overriding method-hiding


【解决方案1】:

我认为第一个问题是你的后代类是否需要被转换为父类。

如果不是,那么最好的方法是使用外观模式,在该模式中隐藏“父级”并只允许通过您的方法访问它。

有点像:

class Parent {
  public double method(double a, double b) { ... }
  public int method(int a, int b) { ... }
}


class YourStuff {
  private Parent _parent = new Parent();

  public int AddNumbers(int a, int b) {
     return _parent.method(a,b);
  }
}

在这种情况下,父类是隐藏的。

【讨论】:

  • 所以这使用composition 而不是继承,我同意这对于提问者来说可能是一个更好的解决方案。不过,不确定这是否是对他问题的回答。当你说_parent 被隐藏时,你在另一个意义上使用了“隐藏”这个词。您说的是一种encapsulation,而在 C# 中,“隐藏”通常是指无法访问一个成员(或命名空间等)的情况,因为另一个具有相同名称的成员具有更高的“优先级”。跨度>
【解决方案2】:

这不是方法隐藏的工作方式。您的 private new 方法仅隐藏了 Child 类中的原始方法(但他们称其为隐藏的内容,因此没有任何收获)。

在派生自Child 的Grandchild 类中,不再隐藏任何内容,因为private new 方法不在范围内,因此Parent 的public 方法完全可调用且“裸”。方法隐藏不会以任何方式移除隐藏的方法;这只是调用哪个相同方法的问题。

【讨论】:

  • 并且int 和System.Int32 是同义词,因此您的最后两个重载已经在第一级发生冲突(当然这是不允许的)。
【解决方案3】:

如果您希望您的库类父方法名称 Method 不能从外部调用,您需要更改访问修饰符。您的类没有访问修饰符,因此默认为 Internal - 同一程序集中的任何代码都可以访问类型或成员,但不能从另一个程序集中访问。 Method Method 具有相同的可访问性,因为它具有访问修饰符 public。如果您希望在类 Method 中实现的方法只能对派生类实例进行访问,则您需要所有访问修饰符 public 用于重载的 Method 变体更改为受保护,然后在子类中隐藏此方法重载的方法。如果您希望从外部使用这些隐藏方法,您需要将它们的访问修饰符从私有更改为公共。此实现示例:

namespace HideBaseClassMethod
{
    class Program
    {
        static void Main(string[] args)
        {
            Parent myParent = new Parent();
            //myParent. - no one of overloaded protected methods are accessible after dot operator
           Child myChild = new Child();
           myChild.Method(2.5, 4.3); //double 
           myChild.Method(2, 4);//int

           Parent myChildCreatedAsParent = new Child();
           //myChildCreatedAsParent.  - no one of overloaded protected methods are accessible after dot operator
        }
    }
    class Parent 
    {
        protected double Method(double a, double b)
        {
           Console.WriteLine($"I am a parent double method {a} + {b}");
           return a + b;
        }
        protected int Method(int a, int b)
       {
            Console.WriteLine($"I am a parent integer method {a} + {b}");
            return a + b;
       }
   }
   class Child:Parent
   {
        public new double Method(double a, double b)
        {
            Console.WriteLine($"I am a child double method {a} * {b}");
            return a * b;
        }
        public new int Method(int a, int b)
        {
            Console.WriteLine($"I am a child integer method {a} * {b}");
            return a + b;
        }
    }
}

这个程序执行的结果是:

我是小孩双法2.5 * 4.3

我是一个子整数方法2 * 4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    相关资源
    最近更新 更多