2012-01-23 3 views
5

Я создаю экземпляр динамически, используя Activator.CreateInstance. Однако он говорит, что объект не может быть нулевым при каждой попытке. Вставка кода ниже. Я что-то делаю неправильно?Activator.CreateInstance failing

Есть ли какие-либо проблемы, если

Activator.CreateInstance

заменяет обычные/оператор регистра переключателя для определения типа объекта в время выполнения? Благодарю.

public abstract class Base 
{ 
    public abstract void Func(); 

} 
public class Derived:Base 
{ 
    public override void Func() 
    { 
     MessageBox.Show("Derived First"); 
    } 
} 

public class Derived2 : Base 
{ 
    public override void Func() 
    { 
     MessageBox.Show("Derived Second"); 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    // I was trying to make use of the overladed version 
    // where it takes the Type as parameter. 
    BaseClass report = 
     (BaseClass) Activator.CreateInstance(Type.GetType("Derived")); 
    report.Func(); 
} 
+0

почему бы вам не использовать TypeOf() вместо Type.GetType() ?? –

ответ

3

Из документации параметра Type.GetTypetypeName:

Сборку квалифицированного имени типа, чтобы получить. См. AssemblyQualifiedName. Если тип находится в выполняемой в настоящее время сборке или в Mscorlib.dll, достаточно указать имя типа , соответствующее его пространству имен.

Это означает, что вам нужно (по крайней мере) передать пространство имен, а также:

BaseClass report = (BaseClass) Activator.CreateInstance(Type.GetType("YourNamespace.Derived")); 
1

Метод GetType не работает и возвращает null. См. Раздел параметров предыдущей ссылки.

Ассемблерное имя типа, которое нужно получить. См. AssemblyQualifiedName. Если тип находится в текущей исполняемой сборке или в Mscorlib.dll, достаточно указать имя типа, соответствующее его пространству имен.

Добавьте пространство имен, прежде чем "Derived" и если Derived класса находится в другой сборке, а затем добавить ", assemblyname" до конца.


Обратите внимание, что если вы не собираетесь изменять строку вы передаете в GetType, то вы могли бы просто использовать typeof(Derived) (хотя и в этом случае нет особого смысла, используя Activator.CreateInstance).

3

Ну, Type.GetType("Derived") почти наверняка возвращается нуль - что бы сделать это ничего общего с Activator.CreateInstance.

Проверил:

  • ли в той же сборке, что и вызывающий код Derived? Если нет, используйте Assembly.GetType на правой сборке или укажите имя сборки в имени типа, которое вы переходите на Type.GetType()
  • Является ли ваш тип в пространстве имен?Если да, то вам нужно пространство имен-квалифицируют
+0

Есть ли проблемы, если этот метод заменяет обычные операторы switch/case для определения типа объекта во время выполнения? Благодарю. – logeeks

+0

@logeeks: Честно говоря, на самом деле не совсем понятно, что вы имеете в виду. –

+0

В моей программе я получаю значение перечисления с сервера. это значение перечисления определит, какой объект должен быть создан. например: млекопитающее mb; switch (MammalType): case Cat: mb = new Cat(); ломать; case Dog: mb = new Dog(); Я спрашивал, могу ли я каким-то образом получить имя значения enum, я могу использовать его, чтобы построить объект класса в одном выражении, а не в зависимости от оператора case switch. Имеет ли этот подход какой-либо недостаток? – logeeks

3

Type.GetType("Derived" не могу найти тип

Simeple изменение

BaseClass report = (BaseClass) Activator.CreateInstance(Type.GetType("Derived")); 

к этому

Base report = (Base)Activator.CreateInstance(typeof(Derived)); 
+1

В этом случае, я думаю, 'Base report = new Derived();' будет еще проще? –

+0

Да, но я думаю, что это (вопрос) было только образцом. – dknaack

+2

Я тоже так думаю, но я также думаю, что ключевым моментом является то, что тип не известен во время компиляции. Если это (как и в вашем ответе), вообще не нужно использовать 'Activator.CreateInstance'. –

0

во время выполнения, ваш GetType вызов будет возврат null. Вы должны:

  • либо Precise пространство имен
  • или использовать TypeOf
Смежные вопросы