C # полиморфизм - как не кодировать типы - PullRequest
1 голос
/ 18 января 2009

Я делаю простую тестовую объектно-ориентированную программу, чтобы попытаться помочь мне разобраться с ООП. У меня есть интерфейс ICommand, который имеет метод Run (параметры params object []), и у меня есть различные классы, которые используют этот интерфейс и реализуют свои собственные версии run. Каждый класс также имеет свойство name, которое сообщает, что это за команда и что она делает.

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

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

О, и я ожидаю, что некоторые ответы скажут, что вы читаете книгу «Шаблоны проектирования»: ну, в данный момент единственная копия в библиотеке отсутствует, но я буду читать ее как можно скорее!

Обновление: Я только что разместил следующий вопрос здесь

Ответы [ 4 ]

2 голосов
/ 18 января 2009

Сохраните все ваши классы в общем списке ICommand, переопределите ToString () именем вашей команды и примените содержимое списка к вашему списку.

var commandlist = new List<ICommand>();
commandList.add(new Command("Run"));
commandList.add(new Command("Walk"));
commandList.add(new Command("Crawl"));
1 голос
/ 18 января 2009

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

 var commands = new List<object>();
 foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
 {
    foreach (Type type in assembly.GetTypes())
    {
       if (type.GetInterface(typeof(ICommand).FullName) != null)
       {
          commands.Add(Activator.CreateInstance(type));
       }
    }
 }

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

Другой подход заключается в чтении файла конфигурации с именами типов для создания экземпляров (и, возможно, даже сборок для загрузки).

Однако в большинстве случаев в этом нет необходимости. Обычно вполне нормально иметь класс CommandFactory, который просто вызывает несколько конструкторов.

1 голос
/ 18 января 2009

используйте шаблон стратегии ( ссылка на википедию ), вы будете выполнять метод с помощью invoke или отражений. Поскольку примеров много, я не буду здесь перечислять.

0 голосов
/ 18 января 2009

Вы можете использовать отражение, чтобы найти все классы, которые реализуют интересующий вас интерфейс; затем используйте это, чтобы заполнить ваш список

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