如何在c#中调用基本重载方法?

时间:2011-01-29 08:52:52

标签: c#

我有以下类层次结构

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

B类可以用于两种情况:

1)

A b = new B();
string result = b.M();

2)

B b2 = new B();
string result2 = b2.M(someString, true);

这两种情况都会因StackOverflowException而崩溃。发生这种情况是因为在B.M(字符串s,bool标志)内调用的base.M(s)将再次调用B.M(字符串s,bool标志)。

有什么好方法可以避免这种情况吗?

据我所知,如果我调用base.M(s,flag),一切都会起作用,但如果其他人开发了一个衍生类并访问base.M(s)怎么办?我不想在这里留下StackOverflowException的可能性。

现在我的层次结构看起来像

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

3 个答案:

答案 0 :(得分:6)

通常这里的诀窍是一个 virtual(通常是参数最多的那个),这是你唯一一个垂直调用的。其他可能是非虚拟的,只需使用适当的默认值调用“主”。

答案 1 :(得分:2)

我会选择这样的东西:

class A
{
    public virtual string M(string s = "", bool flag = false)
    {
        // Some base logic here
    }
}

而不是有3个重载方法,这些方法最终都使用硬编码参数调用相同的方法。

答案 2 :(得分:0)

你不应该这样做,但有时当你需要一个廉价的'hacky'解决方案时,你可以做到以下几点:

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

或者(这个比上面更合适)你可以创建一个虚拟方法,该方法对于孩子(Bar)是空的而不是调用base而是为了父(Foo)它做事:

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