简体   繁体   English

用 arguments 实现比接口声明中派生更多的接口成员?

[英]Implementing interface member with arguments that are more derived than in those in the interface declaration?

Is there a way to implement this so that I can use overloaded methods with more derived arguments?有没有办法实现这一点,以便我可以使用具有更多派生 arguments 的重载方法? The overloaded methods aren't matching the signature as defined in the interface, even though they inherit from the Command class, but they should still be interchangeable, right?重载的方法与接口中定义的签名不匹配,即使它们继承自Command class,但它们应该仍然可以互换,对吧?

public class Command {}

public interface IHandler
{
    public Result Handle(Command cmd);
}

public class CommandOne : Command {}
public class CommandTwo : Command {}

public class HandlerA: IHandler
{
    public Result Handle(CommandOne cmd) {...}
    public Result Handle(CommandTwo cmd) {...}
}

I suppose this is not allowed since it would allow you to do this which doesn't make sense:我想这是不允许的,因为它会让你这样做,这是没有意义的:

public class CommandThree : Command {}

public class HandlerB: IHandler
{
    public Result Handle(CommandOne cmd) {...}
    public Result Handle(CommandThree cmd) {...}
}

IHandler handler = new HandlerA();

handler.Handle(new CommandThree()); // this is not defined

But is there a way to get around this like implementing a default method that would get called if there is no matching signature?但是有没有办法解决这个问题,比如实现一个默认方法,如果没有匹配的签名就会被调用? Like so:像这样:

public class HandlerC: IHandler
{
    public Result Handle(CommandOne cmd) {...}
    public Result Handle(CommandTwo cmd) {...}

    public Result Handle(Command cmd) {...}
}

This compiles but will lead to a NotImplementedException when I try to call the Handle method with any derived class. I'm assuming this is because the interface only has that one method with the signature using the Command class.这会编译,但当我尝试使用任何派生的 class 调用 Handle 方法时会导致NotImplementedException 。我假设这是因为接口只有一个方法,其签名使用Command class。

IHandler handler = new HandlerC();
handler.Handle(new Command()); // works
handler.Handle(new CommandOne()); //NotImplementedException

Is there even a way to get this to work?甚至有办法让它发挥作用吗?

You must implement the interface as it is declared, so you must declare a method with a parameter of the base class type.您必须按照声明的方式实现接口,因此您必须声明一个带有基本 class 类型参数的方法。 You can overload the method with parameters of more specific types though.不过,您可以使用更具体类型的参数重载该方法。 Only the interface method can be called via a reference of the interface type, but you can implement that method such that it calls the other overloads if the argument is the appropriate type, eg只能通过接口类型的引用调用接口方法,但是您可以实现该方法,以便在参数是适当的类型时调用其他重载,例如

public class HandlerD : IHandler
{
    public Result Handle(CommandOne cmd) { /* ... */ }
    public Result Handle(CommandTwo cmd) { /* ... */ }

    public Result Handle(Command cmd)
    {
        if (cmd is CommandOne cmd1)
        {
            return Handle(cmd1);
        }

        if (cmd is CommandTwo cmd2)
        {
            return Handle(cmd2);
        }

        // Default implementation here.
    }
}

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

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