Hide a base class method in a generic derived class

我只是一个虾纸丫 提交于 2019-12-01 20:35:47

问题


I have a base class like this:

class FooBase
{
    public bool Do(int p) { /* Return stuff. */ }
}

And a child class like this:

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

If the user creates a Foo<string> object called "fooString", then he can call both fooString.Do(5) and fooString.Do("test") but if he creates a Foo<int> object called "fooInt", he can only call the Do method of the derived class. I prefer the second no matter what the T is.

The Do methods in both of these classes essentially do the same thing. The one in the derived class gets an integer from a Dictionary<T, int> using the given parameter and calls the Do method of the base class using it.

That's why I want to hide the Do method of the FooBase in Foo<T>. How can I achieve this or something similar? Any design advice to overcome this would also be nice.


回答1:


but if he creates a Foo<int> object called "fooInt", he can only call the Do method of the derived class.

No, that's not true. If the declared type of the variable is FooBase, it will still call the FooBase method. You're not really preventing access to FooBase.Do - you're just hiding it.

FooBase foo = new Foo<int>();
foo.Do(5); // This will still call FooBase.Do

Full sample code to show that:

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

That's why I want to hide the Do method of the FooBase in Foo.

You need to think about Liskov's Substitutability Principle.

Either Foo<T> shouldn't derive from FooBase (use composition instead of inheritance) or FooBase.Do shouldn't be visible (e.g. make it protected).




回答2:


You could build a base class that is abstract with a protected Do method, and rewrite your current FooBase class to inherit from 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;
    }
}

(of course change the class names)



来源:https://stackoverflow.com/questions/11758411/hide-a-base-class-method-in-a-generic-derived-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!