识别数组中基类的实现

时间:2013-03-07 14:51:23

标签: c# design-patterns casting magic-string

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

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

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

  1. 检查其中一个引擎是否为Engine2类型 - 如果有另一个类执行相同任务但名称不同,则必须在EngineBuilder和EngineFacade中更改它。
  2. 使用标识符字符串检查 - 我真的不喜欢魔术字符串。
  3. 我在客户端网站上所知道的是,或者应该有一个关注网格的引擎。但我不知道更多。

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

1 个答案:

答案 0 :(得分:1)

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

[AttributeUsage(AttributeTargets.Class)]
public class HandlesGridAttribute : Attribute { }

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

[HandlesGrid]
public Engine2 : EngineBase { ... }

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

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;

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

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