在非类似集合的类中使用泛型

时间:2010-09-08 05:01:57

标签: c# design-patterns generics class

我正在研究一种引擎,该引擎可由用户(不是最终用户,库用户)配置以使用不同的组件。 例如,假设课程Drawer必须包含IToolPencilBrush,以及IPatternPlain或{{1} }}。另外,假设Mosaic必须BrushIMaterial

Copper

假设选择WoodPencil的效果实际上是截然不同的,Brush类型也是如此。使用如下通用概念对IPattern类进行编码是不是一个坏主意:

Drawer

然后可以使用该类:

public class Drawer<Tool, Pattern> where Tool: ITool where Pattern : IPattern { ... }
public class Brush<Material> where Material : IMaterial { ... }

我主要使用泛型用于集合等等,并且没有真正看到泛型用于那种事情。我应该吗?

3 个答案:

答案 0 :(得分:3)

除非您创建的引擎具有带参数的方法或泛型类型的返回类型,否则使用泛型并不合理。即你会期望有一个属性和方法,如

public <Material> Material { get; }
public void Draw(<Tool> pen);

(我目前处于Java模式,所以如果错误请更正C#语法!)

从我从示例中可以看出,您只使用泛型作为类的构造函数。由于您依赖于实现中的接口,因此使用泛型并不能真正增加价值。

也许我错了,但泛型确实是为了在编译时检查类型安全并避免大量(冒险)类型转换。

答案 1 :(得分:2)

它可以工作,但这取决于通过构造函数传递ITool / IPattern是否会有所不同。部分取决于方便性,部分取决于您是否对模板参数做了任何有趣的事情(例如,new)。

老实说,给出的例子 not 很好地适应了泛型 - 例如,你不能方便地拥有一组画笔(除非你有一些额外的抽象 - 也许IBrush - 未显示。)

标准winforms(system.drawing.dll)通过静态属性执行此操作,例如Pens.RedBrushes.Blue(对于基本的实体画笔) - 可能从那里获得一些灵感?或者可能不是。由你决定。

答案 2 :(得分:2)

在这种情况下,我赞成合成优于泛型。我想,虽然工具将是抽屉的责任,但模式将是工具的责任。

public class Drawer
{
    private ITool _tool;

    public Drawer(ITool tool, IPattern pattern)
    {
        _tool = new Tool(pattern);
    }
    ...
}

public class Tool : ITool
{
    private IPattern _pattern;

    public Tool(IPattern pattern)
    {
        _pattern = pattern;
    }
    ...
}