Отражение C #: создание объекта с именем класса строки - PullRequest
9 голосов
/ 13 августа 2011

Моя ситуация такова: я работаю с Visual C # 2010 Express над разработкой приложения для Windows Forms.Когда пользователь входит в систему, динамически строит меню с опциями, загруженными из таблицы базы данных.В этой таблице я сохраняю идентификатор, имя опции и имя формы.

Итак, предположим, что в моем проекте у меня есть форма с именем Contabilidad, у нее есть Contabilidad.cs, который является основным классом, поэтому, если я хочу создатьНовая форма и показать это я делаю это:

Contabilidad frmConta = new Contabilidad();
frmConta.Show();

Но в этом случае, поскольку пункты меню хранятся в базе данных, в базе данных у меня есть только строка "Contabilidad".Итак, я хочу использовать отражение C # для создания экземпляра Contabilidad или любой другой формы только с именем класса в строковом формате.

Сначала я попробовал это:

Form frmConta= (Form)Activator.CreateInstance(null, "Contabilidad").Unwrap();

Потому что я читал ввопрос StackOverflow о том, что если я использую значение null, я имею в виду текущую сборку (все мои формы находятся в одном проекте), но я получаю это сообщение:

Could not load type 'Contabilidad' from assembly 'AccountingSA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Определение класса следующее:

namespace AccountingSA {
public partial class Contabilidad : Form
{
    public Contabilidad()
    {
        InitializeComponent();
    } ...

Также я попробовал это:

Assembly assembly = Assembly.Load("AccountingSA");
Type t = assembly.GetType("Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);

Но я получаю ArgumentNullException с этим сообщением:

Value cannot be null. Parameter name: type

Поскольку переменная t равна нулю.

Что я делаю не так?Заранее спасибо.

Ответы [ 6 ]

15 голосов
/ 13 августа 2011

Используйте полное имя типа:

Type t = assembly.GetType("AccountingSA.Contabilidad");

Из документации на Assembly.GetType(string):

name Тип: System.String Полное название типа. [...] Параметр name включает пространство имен, но не сборку.

13 голосов
/ 13 августа 2011

Вы пытаетесь использовать имя класса без указания пространства имен.Это должно быть хорошо:

Assembly assembly = Assembly.Load("AccountingSA");
Type t = assembly.GetType("AccountingSA.Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);

Для каждой версии GetType требуется полное имя типа;Преимущество использования Assembly.GetType состоит в том, что, по крайней мере, вам не нужно также включать имя Assembly , но, как указано в документации, вам все еще нужно пространство имен:

Параметр name включает пространство имен, но не сборку.

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

1 голос
/ 13 августа 2011

Попробуйте это

Form frmConta= (Form)Activator.CreateInstance(null, "AccountingSA.Contabilidad").Unwrap();
1 голос
/ 13 августа 2011

Вы должны добавить пространство имен:

assembly.GetType("AccountingSA.Contabilidad");
0 голосов
/ 03 ноября 2017

Слишком поздно в потоке, чтобы ответить, но более ранний ответ в текущей среде .NET (4.7) не работает (строка Assembly Assembly = Assembly.Load ("AccountingSA"); всегда вызывает исключение FileIOException). В настоящее время рабочий код (использовать тип непосредственно)

Type t = Type.GetType("AccountingSA.Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);

или другой способ, использующий сборку

Assembly assembly = typeof(Form).Assembly;
Type t = assembly.GetType("AccountingSA.Contabilidad");
Form frmConta = (Form)Activator.CreateInstance(t);
0 голосов
/ 13 августа 2011

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

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