c# - 将包含对象作为参数传递给包含对象的方法是不是不好的设计?

标签 c# oop containment

将包含对象作为参数传递给包含对象的方法(如下面的简化示例所示)是不是不好的设计?

class A
{
    private B _containedObject;

    public A(B b)
    {
            _containedObject = b;
            //...
    }

    public void SomeMethod()
    {
            //...
            _containedObject.SomeMethod(this);
            //...
    }
}

class B
{
    public void SomeMethod(A a)
    {
            //do something with a
    }
}

P.s.上面的例子只是为了说明包含关系以及将包含对象传递给被包含对象而进行简化,其本身并没有说明这样做的目的。不过请放心,这是有目的的。

最佳答案

有时您可能希望将包含对象作为参数传递给被包含对象。正如其他发帖者所指出的,这被称为“双重调度”。 Smalltalk 语言提供了一个典型的例子。

该示例是将整数和 float (或其他类型的数字)相加。在 C++ 或 Java 中,您的整数类将具有多态方法,例如:

Integer {
     add(Float) {...}
     add(Integer) {...}
     add(UserDefinedType) {...}
}

每种add方法都可以实现不同类型的加法正确。编译器使用类型信息来选择正确的方法。语句 Integer(6).add(Float(1.0)) 将调用 Integer::add(Float) 方法。

与 C++ 和 Java 不同,Smalltalk 是动态类型的。一个 Smalltalk 类只能有一个名为 add 的方法。

整数::add(对象)

编译器不知道“object”的类。因此,Smalltalk 无法像 C++ 或 Java 那样实现add。相反,Smalltalk 使用双重调度。它的工作原理如下:

   Integer {
          add(Object o) {
              return o.addToInteger(this)
          }        
    }

其他数字类,如 Float、Fraction 甚至 Integer 都实现了 addToInteger() 方法。

Float {
      addToInteger(Object o) {
          //Perform float + in math
          return result
     }
}

双分派(dispatch)解决了如何在动态类型语言中多态地实现man操作的问题。但还有一个更常见的用途:访问者模式。我会将其放在单独的答案中。

关于c# - 将包含对象作为参数传递给包含对象的方法是不是不好的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8712850/

相关文章:

c#如何在foreach语句中获取最后一次?

delphi - 在 Delphi 中阻止函数被覆盖

swift - UIPageViewController:调用 viewDidLoad 时 socket 未初始化

c# - 在 MessageBoxManager 上设置超时

c# - 缓存 ASP.NET MVC Web API 结果

c# - 如何在类库中正确调用 P/Invoke 方法?

php - 从数据库填充下拉列表

c++ - 在开关中声明类对象,然后在开关外使用该变量

Java - 从一个方法返回多个对象类型的最佳方式

iphone - 使用 View Controller 包含, child 失去 parent