C# 中的双重调度?
我听说过/读过这个词,但不太明白它的意思。
我什么时候应该使用这种技术以及如何使用它? 谁能提供一个好的代码示例吗?
I have heard/read the term but don't quite understand what it means.
When should I use this technique and how would I use it? Can anyone provide a good code sample?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
工作代码的完整列表
Full listing of working code
C# 4 引入了伪类型
dynamic
,它在运行时(而不是编译时)解析函数调用。 (即使用表达式的运行时类型)。 双(或多调度)可以简化为:另请注意,通过使用动态,您可以防止编译器的静态分析器检查这部分代码。 因此,您应该仔细考虑使用
动态
。C# 4 introduces the pseudo type
dynamic
which resolves the function call at runtime (instead of compile time). (That is, the runtime type of the expression is used). Double- (or multi-dispatch) can be simplified to:Note also by using
dynamic
you prevent the static analyzer of the compiler to examine this part of the code. You should therefore carefully consider the use ofdynamic
.其他答案使用泛型和运行时类型系统。 但需要明确的是,泛型和运行时类型系统的使用与双重分派没有任何关系。 它们可以用来实现它,但双重调度仅依赖于在运行时使用具体类型来调度调用。 我认为在维基百科页面中更清楚地说明了这一点。 我将在下面包含翻译后的 C++ 代码。 其中的关键是 SpaceShip 上的虚拟 CollideWith,并且它在 ApolloSpacecraft 上被覆盖。 这是“双重”调度发生的地方,并且为给定的宇宙飞船类型调用正确的小行星方法。
The other answers use generics and the runtime type system. But to be clear the use of generics and runtime type system doesn't have anything to do with double dispatch. They can be used to implement it but double dispatch is just dependent on using the concrete type at runtime to dispatch calls. It's illustrated more clearly I think in the wikipedia page. I'll include the translated C++ code below. The key to this is the virtual CollideWith on SpaceShip and that it's overridden on ApolloSpacecraft. This is where the "double" dispatch takes place and the correct asteroid method is called for the given spaceship type.
马克发布的代码不完整,并且其中的内容无法正常工作。
如此调整并完成。
感谢 Mark 和其他人对双调度程序模式的精彩解释。
The code posted by Mark isn't complete and what ever is there isn't working.
So tweaked and complete.
Thanks Mark and others for nice explanation on Double Dispatcher pattern.
访问者模式是一种以面向对象的方式进行双重调度的方法。
当您想要在运行时而不是编译时根据给定参数的类型选择使用哪个方法时,它非常有用。
双重调度是多重调度的一种特殊情况。
当您在对象上调用虚拟方法时,这被视为单次调度,因为调用哪个实际方法取决于单个对象的类型。
对于双重分派,对象的类型和方法唯一参数的类型都会被考虑在内。 这类似于方法重载解析,只不过参数类型是在运行时以双重调度确定的,而不是在编译时静态确定的。
在多重分派中,一个方法可以传递多个参数,并且使用哪个实现取决于每个参数的类型。 评估类型的顺序取决于语言。 在 LISP 中,它从头到尾检查每种类型。
具有多重分派的语言使用泛型函数,这些函数只是函数声明,与使用类型参数的泛型方法不同。
要在 C# 中进行双重分派,您可以声明一个具有唯一对象参数的方法,然后声明具有特定类型的特定方法:
The visitor pattern is a way of doing double-dispatch in an object-oriented way.
It's useful for when you want to choose which method to use for a given argument based on its type at runtime rather than compile time.
Double dispatch is a special case of multiple dispatch.
When you call a virtual method on an object, that's considered single-dispatch because which actual method is called depends on the type of the single object.
For double dispatch, both the object's type and the method sole argument's type is taken into account. This is like method overload resolution, except that the argument type is determined at runtime in double-dispatch instead of statically at compile-time.
In multiple-dispatch, a method can have multiple arguments passed to it and which implementation is used depends on each argument's type. The order that the types are evaluated depends on the language. In LISP, it checks each type from first to last.
Languages with multiple dispatch make use of generic functions, which are just function delcarations and aren't like generic methods, which use type parameters.
To do double-dispatch in C#, you can declare a method with a sole object argument and then specific methods with specific types: