Принудительное применение значения переменной типа как специального базового типа

#c# #.net #reflection #module

#c# #.net #отражение #модуль

Вопрос:

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

 public abstract class Module
{
    public abstract Type ConfigurationForm { get; }
}
  

При отображении формы конфигурации я просто создаю экземпляр формы этого типа и вызываю Show() метод.

Проблема в том, что я хочу заставить модуль возвращать тип, который является подклассом System.Windows.Forms.Form , поскольку в противном случае вызов завершился бы неудачей. Каков правильный способ принудительного применения этого?

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

Комментарии:

1. Есть ли какая-либо причина, по которой ConfigurationForm свойство не может использовать возвращаемый тип Form ?

2. Тип формы конфигурации меняется от модуля к модулю, поскольку он унаследован от Form . Или вы имеете в виду, что я должен создать экземпляр самой формы в коде модуля?

Ответ №1:

Вы могли бы выполнить это с помощью параметра универсального типа

 public abstract class Module<F> where F : Form
{
    public Type ConfigurationForm { get { return typeof(F); } }
}
  

Но на самом деле это могло бы иметь больше смысла:

 public abstract class Module
{
    public abstract Form CreateConfigurationForm();
}
  

Редактировать: Преимущество использования 2-го варианта заключается в том, что вы можете написать код для работы с вашим классом Module, не зная конкретно, с каким типом модуля вы имеете дело

Комментарии:

1. Да, определенно! Не знаю, почему я хотел создать экземпляр формы вне модуля… Спасибо!

Ответ №2:

Не существует способа ограничить возврат функции Type , которая представляет тип, наследуемый от Form . Что вы могли бы сделать, чтобы вернуть форму напрямую:

 public abstract Form CreateConfigurationForm();
  

или фабричный метод (или, альтернативно, фабричный класс):

 public abstract Func<Form> ConfigurationFormCreator();
  

Другим вариантом было бы использовать обобщения, как предложил эраш.