4

我有一个这样的基类:

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>使用给定参数从 a 中获取一个整数,并使用它调用基类的 Do 方法。

这就是为什么我要隐藏FooBasein的 Do 方法Foo<T>。我怎样才能做到这一点或类似的东西?任何克服这个问题的设计建议也很好。

4

2 回答 2

6

但是如果他创建了一个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
    }
}

这就是为什么我想在 Foo 中隐藏 FooBase 的 Do 方法。

您需要考虑Liskov 的可替代性原则

要么 Foo<T>不应该派生自FooBase(使用组合而不是继承),要么 FooBase.Do不应该是可见的(例如使其受保护)。

于 2012-08-01T11:47:39.447 回答
0

您可以使用方法构建一个抽象的基类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;
    }
}

(当然改变类名)

于 2012-08-01T11:47:33.417 回答