Использование Generics в не подобном коллекции классе - PullRequest
5 голосов
/ 08 сентября 2010

Я работаю над механизмом, который должен настраиваться пользователем (не конечным пользователем, пользователем библиотеки) для использования различных компонентов. Например, скажем, класс Drawer должен иметь ITool, Pencil или Brush и IPattern, Plain или Mosaic. Также, скажем, Brush должен иметь IMaterial либо Copper, либо Wood

Скажем, эффект выбора Pencil или Brush действительно радикально отличается, и то же самое относится к типу IPattern. Будет ли плохой идеей кодировать класс Drawer с помощью общих понятий, таких как:

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

Затем можно использовать этот класс как:

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

В основном я использовал дженерики для коллекций и тому подобного, и на самом деле не видел дженериков, используемых для такого рода вещей. Должен ли я?

Ответы [ 3 ]

3 голосов
/ 08 сентября 2010

На самом деле не имеет смысла использовать обобщенные типы, если созданный вами движок не имеет методов с аргументами или возвращаемых типов универсального типа. То есть вы ожидаете, что там будут свойства и методы, такие как

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

(Я в настоящее время нахожусь в режиме Java, поэтому, пожалуйста, исправьте синтаксис C #, если неверный!)

Из того, что я могу сказать из примера, вы используете только дженерики для конструктора классов. Поскольку вы полагаетесь на интерфейсы в своей реализации, использование обобщений на самом деле не добавляет ценности.

Возможно, я ошибаюсь, но generics действительно проверяется на безопасность типов во время компиляции и во избежание большого (рискованного) приведения типов.

2 голосов
/ 08 сентября 2010

В этой ситуации я бы предпочел композицию дженерикам.Я полагаю, что ответственность за инструмент лежит на выдвижном ящике, а образец - на инструменте.

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 голосов
/ 08 сентября 2010

Это может работать, но это зависит от того, будет ли оно отличаться от передачи ITool / IPattern через конструктор.Отчасти зависит от удобства, а отчасти от того, делаете ли вы что-нибудь интересное с параметрами шаблона (например, new их).

Если честно, приведенный пример делает не скачокна ум, как подходящий для дженериков - например, у вас не может быть набора кистей (если у вас нет какой-то дополнительной абстракции - возможно, IBrush - не показана).

Стандартные winforms (система.drawing.dll) делает это через статические свойства, такие как Pens.Red, Brushes.Blue (для основной твердой кисти) - может быть, оттуда черпать вдохновение?а может и нет.До вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...