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语言提供了一个经典示例。

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

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


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

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

整数:: add(Object)

编译器不知道“对象”的类。因此,Smalltalk无法实现与C ++或Java相同的添加方式。相反,Smalltalk使用双重调度。它是这样的:

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


其他数字类(例如Float,Fraction和Integer)实现方法addToInteger()。

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


双重调度解决了如何以动态类型的语言多态实现人工操作的问题。但是还有一个更普遍的用途:访问者模式。我将其单独回答。

相关文章:

c# - 有没有更好的方法来使用Json.Net处理编码值?

java - 以电子电路类为例正确使用聚合(OOP)

jquery - jQuery可拖动无法与遏制一起使用

ios - 将嵌套在容器 View Controller 内的UINavigationController添加到UITabBarController

c# - 无法让.Dispose()在foreach循环中工作

c# - 网站和移动应用程序的成员(member)制

c# - 获取网络打印机列表silverlight

python - Ruby如何比Python更面向对象?

c# - C#创建类和派生类的实例

javascript - jQuery中的.sortable函数问题