简体   繁体   English

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

[英]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: B类可用于两种情况:

1) 1)

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

2) 2)

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

Both cases crash with StackOverflowException. 这两种情况都会因StackOverflowException而崩溃。 This happens because base.M(s) which is called inside BM(string s, bool flag) will call BM(string s, bool flag) again. 这是因为在BM内部调用的base.M(字符串s,bool标志)将再次调用BM(字符串s,bool标志)。

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) ? 我明白,如果我调用base.M(s,flag),一切都会起作用,但如果其他人开发了一个衍生类并访问base.M(s)怎么办? I don't like to leave a possibility of StackOverflowException here. 我不想在这里留下StackOverflowException的可能性。

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. 通常这里的技巧是拥有一个 virtual (通常是具有大多数参数的virtual ),这是您唯一一个垂直调用的virtual 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. 而不是有3个重载方法,这些方法最终都使用硬编码参数调用相同的方法。

You shouldn't really do this, but sometimes when you need a cheap 'hacky' solution you can do the following: 你不应该真的这样做,但有时当你需要一个廉价的'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);
    }
}

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: 或者(这个比上面更合适)你可以创建虚拟方法,对于子( 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...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM