How to call base overloaded method in c#?
I have the following class hierarchy
class A
{
public virtual string M()
{
return M(String.Empty);
}
public virtual string M(string s)
{
return M(s, false);
}
public virtual string M(string s, bool flag)
{
// Some base logic here
}
}
class B:A
{
public override string M(string s, bool flag)
{
string baseResult = base.M(s);
// Derived class logic here
}
}
The class B can be used in two cases:
1)
A b = new B();
string result = b.M();
2)
B b2 = new B();
string result2 = b2.M(someString, true);
Both cases crash wit开发者_开发百科h StackOverflowException. This happens because base.M(s) which is called inside B.M(string s, bool flag) will call B.M(string s, bool flag) again.
Is there any good way to avoid this?
I understand that if I call base.M(s, flag) everything will work, but what if someone else develops a dervived class and access base.M(s) ? I don't like to leave a possibility of StackOverflowException here.
SOLUTION
Now my hierarchy will look like
class A
{
public string M()
{
return M(String.Empty, false);
}
public virtual string M(string s, bool flag)
{
// Some base logic here
}
}
class B:A
{
public override string M(string s, bool flag)
{
string baseResult = base.M(s, flag);
// Derived class logic here
}
}
Usually the trick here is to have one virtual
(usually the one with most parameters), and this is the only one you call vertically. The others might be non-virtual and just call the "main" one with appropriate defaults.
I would go with something like this:
class A
{
public virtual string M(string s = "", bool flag = false)
{
// Some base logic here
}
}
instead of having 3 overloaded methods which all end up calling the same method with hard-coded parameters.
You shouldn't really do this, but sometimes when you need a cheap 'hacky' solution you can do the following:
public interface IFooBar
{
void DoSomething(Object obj);
}
public class Foo
{
public virtual void DoSomething(Object input)
{
this.DoSomething(input, false);
}
protected virtual void DoSomething(Object input, bool skipSomeBits)
{
//Does stuff for Foo and Bar
if (!skipSomeBits)
{
//Does stuff that is specific to Foo but does not need to happen to Bar
}
}
}
public class Bar : Foo
{
public override void DoSomething(object input)
{
base.DoSomething(input, true);
}
}
Or (This one is more appropriate than above) you can create virtual method that for child (Bar
) is empty and does not call base
but for parent (Foo
) it does things:
public interface IFooBar
{
void DoSomething(Object obj);
}
public class Foo
{
public virtual void DoSomething(Object input)
{
//Does Foo and Bar stuff
this.DoSomething2(input);
}
protected virtual void DoSomething2(Object input)
{
//Does Foo stuff
}
}
public class Bar : Foo
{
protected override void DoSomething2(Object input)
{
//Does not call base.DoSomething2() therefore does nothing or can do Bar stuff if needs be...
}
}
精彩评论