Скрыть метод базового класса в универсальном производном классе

У меня есть базовый класс, как это:

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

(конечно измените имена классов)

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