继承:无法从基础 class 访问方法

Inheritance: Unable to access method from base class

我正在实施 CQRS 模式。为了在我的项目中使用 CQRS 模式,我写了三个命令,它们是

public class DogCommand : PetCommand
{
    public DogCommand(){}
    public override string Name{get; set;}
}

public class CatCommand : PetCommand
{
    public CatCommand(){}
    public override string Name{get; set;}
}

public abstract class PetCommand : ICommand
{
    public PetCommand(){}
    public virtual string Name{get; set;}
}

public interface ICommand
{
   //Business logic
 }

这里我有一个名为 ICommand 的界面。 PetCommand 是实现此接口的基础 class。派生 class DogCommandCatCommand 继承 PetCommand.

我也写了基本命令处理程序,如下

public abstract class BaseCommandHandler<T> : CommandHandler<T> where T : ICommand
{
    protected BaseCommandHandler(string type, string name): base(type, name)
    {

    }
}
public abstract class CommandHandler<T> : ICommandHandler<T> where T : ICommand
{
   protected CommandHandler(string type, string name)
   {
    //Business logic
   }

   protected void LogWrite(T command)
   {
      //Writing log 
   }
}


public interface ICommandHandler<in T> where T : ICommand
{
    void Run(T command);
}

BaseCommandHandler 中存在的所有函数,我将在每个派生命令处理程序中使用

现在问题出在派生的 class 命令处理程序中

public class PetCommandHandler : BaseCommandHandler<DogCommand>, ICommandHandler<CatCommand> 
{

    public void Run(DogCommand dCommand)
    {
        this.LogWrite(dCommand)      
    }

    public void Run(CatCommand cCommand)
    {
       **//Want to access this.LogWrite() with cCommand. How can I do that?**          
    }
}

这里我无法访问 cCommand 的 this.LogWrite() 函数,因为 PetCommandHandler 继承了 first BaseCommandHandler然后 实施 ICommandHandle。

How to access this.LogWrite() function for cCommand?

这里是编译时错误:

cannot convert from ‘Command.DogCommand’ to ‘Command.CatCommand’


更新:

解决此问题的第一种方法:

我可以使用基本命令解决这个问题,即 BaseCommandHandler 中的 PetCommand 而不是 DogCommand。这将帮助我访问 this.LogWrite() 函数中的所有派生 classes,但这将导致我实现我不想做的空 Run(PetCommand petCommand) {} 函数。

第二种方式:

每当我遇到这种情况时,我可以将 LogWrite() 功能更改为 CommandHandleroverride 中的 virtual

如果有人为我提供解决此问题的任何其他解决方案,我将不胜感激。

您有一个设计问题需要解决。

您正在尝试处理泛型 class 中的两个独立类型。这不是一个可扩展的设计。

当创建一个继承自 PetCommand 的新 class 时,您将必须更改 PetCommand 处理程序 class 以实现接口 ICommandHandler<newPetCommand>。这基本上是一个糟糕的设计。

您的命令处理程序 class 应该处理宠物,而不是特定类型的宠物,例如猫或狗。

您需要有如下的 CommandHandler 和 PetCommandHandler class。

public abstract class CommandHandler<T> : ICommandHandler<T> where T : ICommand
{
    protected CommandHandler(string type, string name)
    {
        //Business logic
    }

    //Making Run method abstract so that 
    //individual Handler class can have their own logic in it.
    public abstract void Run(T command);

    //Common implementation for LogWrite.
    //If this also requires override, it can be made virtual 
    //so that deriving class can override the logic.
    protected void LogWrite(T command)
    {
        //Writing log 
    }
}

//PetCommandHandler class now can be used for any class object 
//which is inheriting PetCommand class.
public class PetCommandHandler<T> : BaseCommandHandler<T> where T: PetCommand
{
    public PetCommandHandler(string type, string name) : base(type, name)
    {

    }

    public override void Run(T dCommand)
    {
        this.LogWrite(dCommand);
    }
}

如何测试?

var dog = new DogCommand();
var commandHandler = new PetCommandHandler<DogCommand>("Dog", "Tom");
commandHandler.Run(dog);

var cat = new CatCommand();
var catHandler = new PetCommandHandler<CatCommand>("Cat", "Mini");
catHandler.Run(cat);

如果以后再引入新的PetCommandclass,就说PandaCommand。您仍然可以按如下方式使用 PetHandler。

var pandaHandler = new PetHandler<PandaCommand>("Panda", "Po");
var panda = new PandaCommand();
pandaHandler.Run(panda);

如果您不想为不同的 PetCommand 类型创建单独的 PetCommandHandler 实例。您可以如下更改 PetCommandHandler class。

public class PetCommandHandler : BaseCommandHandler<PetCommand>
{
    public PetCommandHandler(string type, string name) : base(type, name)
    {

    }
    public override void Run(PetCommand dCommand)
    {
        this.LogWrite(dCommand);
    }
}

有了这个 class 你只需要创建一个 PetCommndHandler 的实例,你就可以用 PetCommand

的任何对象执行 Run 方法
var patCommandHandler = new PetCommandHandler("someType", "someName");
patCommandHandler.Run(dog);
patCommandHandler.Run(cat);
patCommandHandler.Run(panda);

希望本文能帮助您解决问题。