Скрыть метод базового класса в универсальном производном классе
У меня есть базовый класс, как это:
class FooBase
{
public bool Do(int p) { /* Return stuff. */ }
}
И детский класс, как это:
class Foo<T> : FooBase
{
private Dictionary<T, int> Dictionary;
public bool Do(T p)
{
int param;
if (!Dictionary.TryGetValue(p, out param))
return false;
return base.Do(param);
}
}
Если пользователь создает Foo<string>
объект называется "fooString", то он может вызвать оба fooString.Do(5)
а также fooString.Do("test")
но если он создает Foo<int>
Объект называется "fooInt", он может вызывать только метод Do производного класса. Я предпочитаю второе, независимо от того, что T
является.
Методы Do в обоих этих классах по сути делают одно и то же. Тот, что в производном классе, получает целое число от Dictionary<T, int>
используя данный параметр и вызывает метод Do базового класса, используя его.
Вот почему я хочу скрыть метод До FooBase
в Foo<T>
, Как я могу добиться этого или что-то подобное? Любой совет дизайна, чтобы преодолеть это также было бы хорошо.
2 ответа
но если он создает
Foo<int>
Объект называется "fooInt", он может вызывать только метод Do производного класса.
Нет это не правда. Если объявленный тип переменной FooBase
, он все равно будет называть FooBase
метод. Вы на самом деле не запрещаете доступ к FooBase.Do
- ты просто прячешь это.
FooBase foo = new Foo<int>();
foo.Do(5); // This will still call FooBase.Do
Полный пример кода, чтобы показать, что:
using System;
class FooBase
{
public bool Do(int p) { return false; }
}
class Foo<T> : FooBase
{
public bool Do(T p) { return true; }
}
class Test
{
static void Main()
{
FooBase foo1 = new Foo<int>();
Console.WriteLine(foo1.Do(10)); // False
Foo<int> foo2 = new Foo<int>();
Console.WriteLine(foo2.Do(10)); // True
}
}
Вот почему я хочу скрыть метод Do в FooBase в Foo.
Нужно подумать о принципе замещаемости Лискова.
Или Foo<T>
не должен происходить из FooBase
(используйте композицию вместо наследования) или FooBase.Do
не должно быть видно (например, сделать его защищенным).
Вы можете построить базовый класс, который является абстрактным с protected Do
метод, и переписать свой текущий FooBase
класс для наследования Foo<T>
:
public abstract class FooBaseAbstract
{
protected bool Do(int p)
{
return true;
}
}
// You can use this one just as your current FooBase class
public class FooBase : Foo<int>
{
}
public class Foo<T> : FooBaseAbstract
{
public bool Do(T p)
{
if (true /* some test here */)
{
return base.Do(4);
}
return false;
}
}
(конечно измените имена классов)