Как скрыть все переопределения родительского метода в C#

Я расширяю класс библиотеки, который имеет публичный метод, который я не хочу вызывать извне. Я знаю, что могу скрыть это, используя ключевое слово "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.
}

Но мне интересно, не существует ли более простого способа сделать все переопределения этой функции частными.

2 ответа

Решение

Это не способ, которым скрывается метод. Ваш private new методы скрывают только оригинальные методы внутри Child класс (но они называют то, что они скрывают, так что ничего не получили).

В Grandchild класс, вытекающий из Childбольше ничего не скрыто, потому что private new методы не входят в сферу применения, поэтому public методы Parent прекрасно зовутся и "голые". Скрытие метода никоим образом не удаляет скрытый метод; вопрос только в том, какой из идентичных методов вызывается.

Я думаю, что первый вопрос заключается в том, должен ли ваш класс-потомок быть приведен в качестве родителя.

Если нет, то лучше всего использовать шаблон фасада, в котором вы скрываете "родителя" и разрешаете доступ к нему только через ваши методы.

Вроде как:

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);
  }
}

В этом случае родительский класс скрыт.

Если вы хотите, чтобы метод родительского класса вашего библиотечного класса, имя которого Method не мог быть вызван извне, вам необходимо изменить модификатор доступа. У вашего класса нет модификатора доступа, поэтому по умолчанию он имеет значение Internal - к типу или члену можно получить доступ из любого кода в той же сборке, но не из другой сборки. Такая же доступность есть для метода Method, поскольку у него есть модификатор доступа public. Если вы хотите, чтобы реализованный в классе метод был доступен только для экземпляра производного класса, вам нужно, чтобы все модификаторы доступа были общедоступными для перегруженных вариантов метода, чтобы изменить его на защищенный, а затем в дочернем классе скрыть этот метод перегруженных методов. Если вы хотите, чтобы эти скрытые методы использовались извне, вам необходимо изменить их модификаторы доступа с частных на общедоступные. Пример этой реализации:

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

Другие вопросы по тегам