2011-08-13 10 views
9

moja sytuacja jest następna: Pracuję z Visual C# 2010 express rozwijając aplikację Windows Forms. Kiedy użytkownik się zaloguje, dinamicznie zbuduj menucrip z opcjami załadowanymi z tabeli bazy danych. W tabeli tej zapisuję identyfikator, nazwę opcji i nazwę formularza.C# Reflection: Utwórz instancję obiektu o nazwie klasy String

Więc załóżmy, że w moim projekcie Mam formularz o nazwie contabilidad, ma Contabilidad.cs To jest główny klasy, więc jeśli chcę stworzyć nową postać i pokazać to zrobić to:

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

Ale w tym przypadku, ponieważ opcje menu są przechowywane w bazie danych, w bazie danych mam tylko ciąg "Contabilidad". Tak, chcę użyć C# odbicie, aby utworzyć wystąpienie Contabilidad lub jakiejkolwiek innej formie tylko z nazwą klasy w formacie ciągu.

Najpierw próbowałem to:

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

ponieważ czytałem w pytaniu StackOverflow że jeśli mogę użyć zerowy mówię o obecnym zespole (moje postacie są w ramach tego samego projektu), ale ja się tego komunikat:

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

definicja klasy jest następny:

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

również próbowałem to:

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

ale pojawia ArgumentNullException z tej wiadomości:

Value cannot be null. Parameter name: type 

Ponieważ t zmienna ma wartość null.

Co robię źle? Z góry dziękuję.

Odpowiedz

15

Użyj pełni kwalifikowana nazwa typu:

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

Z dokumentacji dla Assembly.GetType(string):

name Typ: System.String pełna nazwa typu. [...] Parametr nazwy obejmuje przestrzeń nazw, ale nie zespół.

12

Próbujesz użyć nazwy klasy bez określania przestrzeni nazw. To powinno być w porządku:

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

Każda wersja GetType wymaga pełnej nazwy typu; korzyści z korzystania Assembly.GetType jest to, że przynajmniej nie muszą obejmować także montaż nazwy, ale jak udokumentowano trzeba jeszcze przestrzeń nazw:

Parametr nazwa zawiera przestrzeń nazw, ale nie w zespole.

pamiętać, że aby zdiagnozować coś podobnego w przyszłości, to byłoby warte patrząc na wartości t po drugiej linii - to będzie zerowy, dlatego trzecia linia zwrócił wyjątek.

1

Należy dodać przestrzeń nazw:

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

Spróbuj

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

Spróbuj określając swoją klasę w ten sposób:

ContabilidadNamespace.Contabilidad, ContabilidadAssembly 
0

jej zbyt późno w wątku odpowiedzieć, ale wcześniejsza odpowiedź, w aktualnej platformie .NET (4.7), nie działa (The Assembly Assembly = Assembly.Load ("AccountingSA"); lways wyrzuca FileIOException). Obecnie kodeks pracy jest (typ zastosowania bezpośrednio)

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

lub inny sposób korzystania Zgromadzenie jest

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