Using Generics in a Non-Collection Class

I am working on an engine that is intended to be configured by the user (and not the end user, the library user) to use different components. For example, suppose a class Drawermust have ITool, Pencilor Brushand IPattern, Plainor Mosaic. In addition, let a Brushmust have IMaterialeither Copper, orWood

Let's say the effect of the choice Pencilor is Brushreally very different, and the same thing applies to the type IPattern. It would be bad code to encode a class Drawerwith such universal concepts:

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

Then you can use this class, for example:

Drawer<Pencil, Mosaic> FirstDrawer = new Drawer<Pencil, Mosaic>();
Drawer<Brush<Copper>, Mosaic> SecondDrawer = new Drawer<Brush<Copper>, Mosaic>();

Mostly I use generic for collections and such, and actually don't see generics used for this kind of thing. Should I?

+5
source share
3 answers

Actually, it makes no sense to use generics, unless the engine you created has methods with arguments or return types of type type. That is, you would expect that there will be the correct name and methods like

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

(I'm in Java mode now, so please correct the C # syntax if this is wrong!)

From what I can say from the example, you only use generics for the class constructor. Since you rely on interfaces in your implementation, using generics doesn't really add value.

, , generics , () .

+3

, , ITool/IPattern . , , - (, new ).

, - , ( - , IBrush - ).

winforms (system.drawing.dll) , Pens.Red, Brushes.Blue ( ) - , ? . .

+2

In this situation, I would prefer composition over generics. I assume that while the tool will depend on the box, the template will depend on the tool.

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;
    }
    ...
}
+2
source

All Articles