识别数组中基类的实现

Ygg*_*sil 7 c# design-patterns casting magic-string

我有以下问题:我有一组引擎自动(听事件)控制我的模型.下图一般显示了类图: Diagramm级

现在我有一个知道EngineFacade的客户端,我想从客户端设置属性Active从Engine2,但客户端和EngineFacade都不知道三个引擎中的哪一个是Engine2.

有两种方法,但我不喜欢它们中的任何一种:

  1. 检查其中一个引擎是否为Engine2类型 - 如果有另一个类执行相同任务但名称不同,则必须在EngineBuilder和EngineFacade中更改它.
  2. 检查标识符字符串 - 我真的不喜欢魔术字符串.

我在客户端网站上所知道的是,有一个或者应该是一个关注网格的引擎.但我不知道更多.

也许我必须在两个恶魔之间做出选择,但也许你们其中一个人有更好的解决方案.

cas*_*One 1

您可以在 的实现上使用属性Engine2,如下所示:

[AttributeUsage(AttributeTargets.Class)]
public class HandlesGridAttribute : Attribute { }
Run Code Online (Sandbox Code Playgroud)

然后将其应用于您的推导:

[HandlesGrid]
public Engine2 : EngineBase { ... }
Run Code Online (Sandbox Code Playgroud)

然后,在您的客户端中检查属性:

IEnumerable<EngineBase> bases = ...;

// Get all the implementations which handle the grid.
IEnumerable<EngineBase> handlesGrid = bases.
    Where(b => b.GetType().
        GetCustomAttributes(typeof(HandlesGridAttribute), true).Any());

// Set the active property.
foreach (EngineBase b in handlesGrid) b.Active = true;
Run Code Online (Sandbox Code Playgroud)

这里的主要缺点(可能适用于您,也可能不适用于您)是您无法在运行时更改该值(因为该属性是在编译时内置的)。如果您的引擎不是以这种方式动态的,那么该属性是正确的选择。

如果您需要更改派生是否可以在运行时执行此操作,那么您必须回退到第二个选项,即识别引擎属性的代码构造。请注意,它不一定是字符串(我也不喜欢这样),但它可以是更结构化的东西,可以为您提供所需的信息。