gpt4 book ai didi

c# - 如何在 C# 中的接口(interface)上进行多次分派(dispatch)?

转载 作者:太空狗 更新时间:2023-10-29 23:23:17 25 4
gpt4 key购买 nike

假设我有以下类结构:

Class structure

页面

PageStaticPageDynamicPage 接口(interface)将由客户端实现。它们根据页面类型(静态或动态)提供各种数据,用于由 Renderer 呈现页面。这些接口(interface)可能有很多实现。

渲染器

Renderer 渲染页面。此外,此接口(interface)可能有多种实现(针对不同的渲染技术)。

渲染管理器

这只是一个简单的外观,它应该根据给定的页面类型在提供的渲染器上调用适当的渲染方法。这里是

问题

如何根据提供的页面类型确定在 Renderer 对象上调用哪个方法?

当前(不令人满意的)解决方案

目前我正在使用条件调度:

void render(Page page, Renderer renderer) {
if (page is StaticPage) {
renderer.renderStaticPage(page);
} else if (page is DynamicPage) {
renderer.renderDynamicPage(page);
} else {
throw new Exception("page type not supported");
}
}

怎么了

此解决方案的问题在于,每当我希望添加另一种页面类型(即扩展 Page 接口(interface))时,我也需要调整此方法。实际上,这就是面向对象语言中的多态(虚拟)方法应该用于的目的,但在这种情况下这是行不通的(见下文原因)。

我考虑过但拒绝的其他解决方案

  1. 抽象类而不是接口(interface)。这将对实现者的类型层次结构施加不必要的约束:他们将不再能够扩展他们想要的任何类,而是被迫扩展抽象 StaticPageDynamicPage 类,这很糟糕。

  2. 向接口(interface)添加一个dispatch(Renderer render) 方法,并强制实现者根据页面类型在渲染器对象上调用适当的方法。这显然很糟糕,因为实现者不应该关心渲染:他们只需要提供要渲染的数据。

那么,也许有一些模式或一些替代设计可以帮助解决这种情况?欢迎任何想法。 :)

最佳答案

使用动态在运行时选择合适的方法重载:

public class RenderManager
{
public void Render(IPage page, Renderer renderer)
{
try
{
renderer.RenderPage((dynamic)page);
}
catch (RuntimeBinderException ex)
{
throw new Exception("Page type not supported", ex);
}
}
}

但是动态类型当然有性能成本。好处 - 当添加新类型的页面时,您需要更改的只是渲染器 - 只需添加另一个重载方法。


另一个选项是访问者。在这种情况下,每个页面都应该进行调度(似乎是您的第二种方法):

public interface IPage
{
void Render(Renderer renderer);
}

public class StaticPage : IStaticPage
{
public void Render(Renderer renderer)
{
renderer.RenderPage(this);
}
}

public class RenderManager
{
public void Render(IPage page, Renderer renderer)
{
page.Render(renderer);
}
}

在这种情况下,页面“知道”渲染。并且您仍然应该在添加新页面时修改渲染器。

关于c# - 如何在 C# 中的接口(interface)上进行多次分派(dispatch)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18655077/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com