2011-08-13 10 views
9

mi situación es la siguiente: Estoy trabajando con Visual C# 2010 Express el desarrollo de una aplicación de Windows Forms. Cuando el usuario inicie sesión, construya dinámicamente un menú con opciones cargadas desde una tabla de base de datos. En esa tabla, guardo la identificación, el nombre de la opción y el nombre del formulario.C# Reflexión: una instancia de un objeto con nombre de la clase cadena

Por lo tanto, suponer que en mi proyecto tengo un formulario denominado Contabilidad, tiene Contabilidad.cs que es la clase principal, por lo que si quiero crear una nueva forma y mostrar que puedo hacer esto:

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

Pero en este caso, debido a que las opciones del menú están almacenadas en la base de datos, en la base de datos solo tengo la cadena "Contabilidad". Entonces, quiero usar la reflexión de C# para crear una instancia de Contabilidad o cualquier otra forma solo con el nombre de clase en formato de cadena.

En primer lugar he intentado esto:

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

porque he leído en una pregunta StackOverflow que si yo uso nula Me refiero al montaje actual (mis formas están todos en el mismo proyecto), pero me sale este mensaje:

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

la definición de clase es la siguiente:

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

también probé esto:

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

pero consigo ArgumentNullException con este mensaje:

Value cannot be null. Parameter name: type 

Debido a la variable t es nulo.

Lo que estoy mal? Gracias por adelantado.

Respuesta

15

Utilice el nombre completo del tipo:

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

De la documentación para Assembly.GetType(string):

Nombre Tipo: System.String El nombre completo del tipo. [...] El parámetro de nombre incluye el espacio de nombres pero no el conjunto.

12

Está tratando de usar el nombre de la clase sin especificar el espacio de nombres. Esto debe estar bien:

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

Cada versión de GetType requiere el nombre del tipo totalmente cualificado; el beneficio de usar Assembly.GetType es que, al menos, no es necesario incluir también el nombre de ensamblado , pero como se documenta que todavía necesitan el espacio de nombres:

El parámetro de nombre incluye el espacio de nombres pero no el montaje.

Tenga en cuenta que para diagnosticar algo similar en el futuro, habría sido digno de mirar el valor de t después de la segunda línea - será nula, por lo que la tercera línea lanzó una excepción.

1

Usted debe agregar el espacio de nombres:

assembly.GetType("AccountingSA.Contabilidad"); 
1

probar este

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

intente especificar la clase de esta manera:

ContabilidadNamespace.Contabilidad, ContabilidadAssembly 
0

sea demasiado tarde en el hilo para responder, pero la respuesta anterior, en el marco .NET actual (4.7), no funciona (El conjunto de ensamblaje de línea = Assembly.Load ("AccountingSA"); siempre arroja FileIOException). Actualmente, el código de trabajo es (Uso Tipo directamente)

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

u otra manera usando Asamblea es

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