简体   繁体   English

OOP 将子转换为父并返回

[英]OOP convert child to parent and back

I have a general question about OOP I have found the following code in a program (shown as an example).我有一个关于 OOP 的一般性问题我在程序中找到了以下代码(作为示例显示)。 Here a parent class is expected as a parameter, but a child is passed, which is then converted from the parent type back to the child type I am the one who thinks that this kind of back and forth conversion is against the OOP rules or not?这里需要一个父 class 作为参数,但是传递了一个子,然后从父类型转换回子类型 我是认为这种来回转换是否违反 OOP 规则的人?

private void OnSend (BaseParameters obj) {
    var request = commandBuilder.BuildCommand (obj);
    _controller.ReceiveRequest (request);
 }

 public BaseCommand BuildCommand (BaseParameters parameters) {

    switch (parameters) {
       case ParametersCopy parametersCopy: //Give a base parameter and cast to spezific child parameter 
          {
             return = new CommandCopy (parameters.XY.parameters.ZX)
          }
       case ParametersDelete parametersDelete:
          {
             return new CommandDelete (parameters.XY.parameters.ZX);
          }
    }
 }

 //Await a Base command but a child command is passed
 public void ReceiveRequest (BaseCommand cmd) {
    CommandQueue.AddCmd (cmd);
 }

 public void ReceiveEndlessRequest (BaseCommand cmd, CancellationToken cancellationToken) {
    while (!cancellationToken.IsCancellationRequested) {
       var newPram = cmd.Clone ();
       ReceiveRequest (newPram);
    }
 }

This code is still working, because C# only give a refrenze to the object.这段代码仍然有效,因为 C# 只给 object 一个 refrenze。 So you can convert them from parent co child and back.因此,您可以将它们从父 co 孩子转换回来。

My problem is that if I give a pure base command in "ReviceRequest", my application crashes, because the specific command is used internally我的问题是,如果我在“ReviceRequest”中给出一个纯基本命令,我的应用程序就会崩溃,因为内部使用了特定的命令

My "ReviceEndlessRequest" function does not work anymore.我的“ReviceEndlessRequest”function 不再工作了。 Since the copy is executed on the base types, all child properties are lost.由于复制是在基本类型上执行的,因此所有子属性都将丢失。 But since "ReviceRequest" expects the base type everything seems to be ok.但是由于“ReviceRequest”需要基本类型,所以一切似乎都很好。 But the application supports it because parameters are missing.但是应用程序支持它,因为缺少参数。

In my opinion this is a violation of OOP rules.在我看来,这违反了 OOP 规则。 I expect a BaseType and the application works internally with the childType我期望一个 BaseType 并且应用程序在内部使用 childType

Casting the parameters in the BuildCommand is also wrong in my opinion.在我看来,在 BuildCommand 中转换参数也是错误的。 How do you see that?你怎么看?

Casting a base type to a child type is perfectly acceptable as long as you test that it is the appropriate type first, which is what the switch statement in your example is doing.只要您首先测试它是否是适当的类型,将基本类型转换为子类型是完全可以接受的,这就是您示例中的 switch 语句所做的。

There should be a default case in the switch that handles if the parameter is not a known child type.如果参数不是已知的子类型,则开关中应该有一个默认情况来处理。

In a perfect world, you might not need to use this pattern, because all the specialized behavior of subclasses is accessed through polymorphic methods defined on the base.在一个完美的世界中,您可能不需要使用这种模式,因为子类的所有特殊行为都是通过在基础上定义的多态方法来访问的。 What often happens as real systems evolve is that you need some specialized behavior of known subclass types, but can't change the base type.随着实际系统的发展,经常发生的情况是您需要一些已知子类类型的特殊行为,但不能更改基本类型。

The behavior that you see in your code is due to polymorphism.您在代码中看到的行为是由于多态性造成的。 As you know polymorphism states that one thing has many forms.如您所知,多态性表明一件事有许多 forms。 so in your case, CopyCommand or DeleteCommand is one of the forms of Command.因此,在您的情况下, CopyCommand 或 DeleteCommand 是命令的 forms 之一。

BaseCommand does cause an error because it is an abstract form of command. BaseCommand 确实会导致错误,因为它是一种抽象形式的命令。 It has any abstract method which got implemented by its child classes.它具有由其子类实现的任何抽象方法。

BuildCommand method is a kind of Factory Method, which construct your command based on input your provide. BuildCommand 方法是一种工厂方法,它根据您提供的输入构造您的命令。

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

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