#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();
Другим вариантом было бы использовать обобщения, как предложил эраш.