问题
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