Как скрыть все переопределения родительского метода в 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