开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜