9

my situation is the next: I'm working with Visual C# 2010 express developing a Windows Forms Application. When the user logins, dinamically build a menustrip with options loaded from a database table. In that table i save id, option name and Form Name.

So, suppose that in my project i have a Form named Contabilidad, it has Contabilidad.cs that is the main class , so if i wanna create a new form and show it i do this:

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

But in this case, because the menu options are stored in database, in database i only have the string "Contabilidad". So, i want to use C# reflection to create a instance of Contabilidad or any other form only with class name in string format.

First i tried this:

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

Because i read in a StackOverflow question that if i use null i'm referring to current assembly (my forms are all in the same project), but i get this message:

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

The class definition is the next:

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

Also i tried this:

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

But i get ArgumentNullException with this message:

Value cannot be null. Parameter name: type

Because t variable is null.

What i'm do wrong? Thanks in advance.

6 Answers 6

15

Use the fully-qualified name of the type:

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

From the documentation for Assembly.GetType(string):

name Type: System.String The full name of the type. [...] The name parameter includes the namespace but not the assembly.

Sign up to request clarification or add additional context in comments.

Comments

14

You're trying to use the name of the class without specifying the namespace. This should be fine:

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

Every version of GetType requires the fully-qualified type name; the benefit of using Assembly.GetType is that at least you don't need to also include the assembly name, but as documented you still need the namespace:

The name parameter includes the namespace but not the assembly.

Note that to diagnose something similar in the future, it would have been worth looking at the value of t after the second line - it will be null, which is why the third line threw an exception.

Comments

1

You should add the namespace:

assembly.GetType("AccountingSA.Contabilidad");

Comments

1

Try this

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

Comments

0

Try specifying your class this way:

ContabilidadNamespace.Contabilidad, ContabilidadAssembly

Comments

0

Its too late in the thread to answer, but the earlier answer, in current .NET framework (4.7), not working (The line Assembly assembly = Assembly.Load("AccountingSA"); always throws FileIOException). Currently, working code is (Use Type directly)

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

or other way using Assembly is

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.