#c#
#c#
Вопрос:
У меня проблема с объявлением типа, передаваемого из переменной типа параметра.
public static void ShowThisForm(Type passXtraForm, Form parent)
{
var xfrm = passXtraForm.GetType();
xfrm xfrmName = new xfrm();
xfrmName.Show();
}
Могу ли я объявить переменную как тип из passXtraForm.GetType() и объявить ее в другой переменной? Просто передаю тип формы другому классу.
Заранее спасибо за ответ.
Комментарии:
1. Можете ли вы перефразировать вопрос, чтобы сделать его более понятным?
2. Используйте дженерики, вот для чего они нужны.
3. Если вы передаете тип, вы также можете передать объект и использовать отражение, чтобы определить, что делать с объектом.
4. @jeffamaphone: Я думаю, что он хочет передать тип в качестве параметра метода, а затем создать экземпляр этого типа.
5. вот как я это использовал.. ShowThisForm(typeOf(frmMain), this); в методе я не знаю, какой тип passXtraForm, это frmMain или другие формы.. итак, мне нужно создать экземпляр этого типа .. 🙂
Ответ №1:
для этого можно использовать обобщения:
public static void ShowThisForm<T>(T passXtraForm, Form parent) where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
в этом случае аргумент типа ограничен типом формы и типами, производными от формы.
в любом случае, почему у вас этот метод? в статических классах Form и Application есть другие методы для поиска форм в вашем приложении…
Комментарии:
1. Именно то, что я собирался ввести. Хотя я думаю, что первый параметр можно опустить, и вам нужно дополнительное ограничение на:
new()
2. Как насчет «нового» ограничения? Это не будет компилироваться: D
3. вот что вы получаете за то, что записываете это здесь, а не используете редактор, спасибо за подсказку, я обновил ответ, и параметры остаются для ясности (похоже на оригинал)
Ответ №2:
Прежде всего, не похоже, что вам нужен parent
параметр; Я бы полностью его исключил. Тогда я бы использовал дженерики, чтобы сделать то, что вы пытаетесь выполнить:
public static void ShowThisForm<T>() where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
where T : Form, new()
Часть этого кода называется ограничением типа и не позволяет вызывать ShowThisForm
метод с типом, который не имеет конструктора по умолчанию и является производным от Form
него .
Указывая, что T
должен иметь конструктор по умолчанию, компилятор знает, как разрешить new T()
; указывая, что T
происходит от Form
, компилятор знает, как вызвать .Show()
метод.
Итак, если у вас вызывается класс form MyForm
, вы можете использовать следующий синтаксис для вызова этого метода:
ShowThisForm<MyForm>();
Для получения дополнительной документации вам следует ознакомиться с этими статьями в MSDN:
Комментарии:
1. спасибо, сэр, и спасибо за ответы.. получил ответ из этого кода .. 😉
2. @vrynxzent Нет проблем. Я бы посоветовал вам прочитать страницы MSDN, дженерики — это мощная концепция, которую можно использовать для написания более гибкого / повторно используемого кода.
Ответ №3:
Вы могли бы изменить его на что-то более похожее на это:
public static void ShowThisForm<T>() where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
Ответ №4:
Может быть, передать фабрику, чтобы известный интерфейс мог создавать экземпляры любого типа объекта, который вызывающий код считает необходимым?
(приведенный ниже код — это краткий пример, который я ввел здесь; форматирование отключено, и дизайн мог бы быть лучше. Это просто для того, чтобы дать представление)
static class XFactory
{
private int _id;
public XFactory(int formId) {
_id = formId;
}
/// <summary>
/// Decides which class to instantiate.
/// </summary>
public static Form Get()
{
switch (_id)
{
case 0:
return new FormA();
case 1:
case 2:
return new FormB();
case 3:
default:
return new FromC();
}
}
}
public static void Main()
{
ShowThisForm(new XFactory(2));
}
public static void ShowThisForm(XFactory formFactory)
{
var xfrm = formFactory.Get();
xfrm.Show();
}
Комментарии:
1. Это перебор, если мы говорим о чем-то, что наследуется от общего интерфейса, например, WinForm. хех.
Ответ №5:
Вы можете создать экземпляр класса / типа с помощью отражения и активатора.CreateInstance(typ, constructorargs), но, скорее всего, было бы лучше создать объект в другом месте и сделать его либо известным базовым классом (в вашем случае он выглядит как form), либо реализовать определенный интерфейс, который можно использовать для управления им. Очень редко вам нужно создавать объект совершенно неизвестного типа.