首页 > 解决方案 > 为具有不同数量参数的子对象调用父对象的方法

问题描述

今天是个好日子!

想象一下你有这个:

public abstract class CommandParent
{
    public abstract void Execute();
}

public class Command1 : CommandParent
{
    public override void Execute(){}
}

我想为所有 CommandParent 对象调用 Execute() 方法,如下所示:

List<CommandParent> _commandList = new List<CommandParent>();
for (int i = 0; i < _commandList.length; i++)
{
    _commandList[i].Execute(); 
}

但是,如果我有另一个派生自 CommandParent 的类,它有一个 Execute() 方法,但有参数怎么办?我会这样做,

public class Command2 : CommandParent
{
    public override void Execute(string parameter){}
}

但随后的线条

for (int i = 0; i < _commandList.length; i++)
{
    _commandList[i].Execute(); 
}

不会再工作了。这可以通过不同的方法来实现吗?如果可以,具体如何?

提前致谢。

标签: c#inheritanceparameters

解决方案


你在做什么没有意义。

Command2被明确设计为在其方法上需要一个字符串参数Execute,然后您打算在没有该必需参数的情况下调用它。这是明显的意图矛盾。

如果你不提供字符串参数,你的代码怎么能收到这个字符串值?如果字符串值不是代码工作所必需的,那么为什么要在开头添加这个字符串参数呢?


嗯,所以不可能有一个带有 Execute() 方法的 Command1 类和一个带有 Execute(string parameter) 方法的 Command2 类,并用父类的一条语句调用这两种方法?

有很多方法可以做到这一点,但实施起来更复杂。

1

如果所有命令都接受某种输入,您可以使您的基类通用,以便指定输入参数:

public class Command<TExecuteInput>
{
    public abstract void Execute(TExecuteInput input);
}

这也可以是具有泛型类型的接口。这取决于您是否需要此类包含比我的示例更多的逻辑。

然后所有派生类都可以选择其输入参数的类型:

public class StringCommand : Command<string>
{
    public void Execute(string input)
    {
        // ...
    }
}

但是,如果您打算将各种命令存储在一个列表中并不加选择地执行它们,那么拥有一个通用基类将使您的多态性复杂化。

这又变成了一个与期望相矛盾的问题:您需要命令来要求特定(和不同)类型的输入,然后您打算在不知道它们需要什么输入的上下文中使用它们并尝试在不提供的情况下调用它们那个输入。

2

您可以将构造函数用于不同的初始化逻辑。这主要适用于您的命令的生命周期相当短的情况。

public class Command
{
    public virtual void Execute()
    {
        Console.WriteLine("base command handling");
    }
}

public class StringCommand : Command
{
    public StringCommand(string input)
    {
        this.input = input;
    }

    private readonly string input;

    public override void Execute()
    {
        base.Execute();

        Console.WriteLine($"String command handling: {input}");
    }
}

打电话base.Execute()不打电话就看你自己了。

当您采用这种方法时,请非常注意LSP及其违规行为。在这里滑倒并以无法再替代的方式扩展您的课程是很常见的——您应该避免这种情况。


推荐阅读