Как использовать отражение для создания нового класса на основе текста в XML-файле - PullRequest
1 голос
/ 23 апреля 2011

у меня есть базовый Question класс и множество классов, которые наследуются от этого класса, например CheckboxQuestion class и RadioButtonQuestion class

программа перебирает код xml для каждого блока, который находится внутри тега вопроса, создает новый элемент на основе имени тега и является дочерним классом класса Question

        <question number="1">
            <RadioButtonQuestion>
                <title>What is the right ...</title>
                <choices>
                    <choice value="1">answer 1</choice>
                    <choice value="2">answer 2</choice>
                    <choice value="3">answer 3</choice>
                    <choice value="4">answer 4</choice>
                </choices>
            </RadioButtonQuestion>
        </question>

после итерации по всему XML-файлу я хочу поместить все вопросы в IEnumerable<Questions> проблема в том, что я не знаю, как создать новый класс на основе текста, написанного в XML-документе

Ответы [ 3 ]

4 голосов
/ 23 апреля 2011

Если тег XML напрямую отражает имя вашего класса, вы можете использовать Type.GetType() для определения соответствующего типа - имейте в виду, что ему требуется полное пространство имен («Тест» в примере ниже). Затем вы можете использовать Activator.CreateInstance() для создания экземпляра этого типа.

string xmlTagName = "RadioButtonQuestion";
Type type = Type.GetType("Test." + xmlTagName );
var question = Activator.CreateInstance(type);

Также имейте в виду, что Activator.CreateInstance() возвращает object. В целом может быть лучше, если вы определите правильный тип в зависимости от имени тега, а затем создадите экземпляр экземпляра по старинке.

2 голосов
/ 23 апреля 2011

Предполагая, что все типы находятся в текущей выполняемой сборке, это должно создать экземпляр класса по имени, без необходимости в операторе switch:

public object InstantiateClass(string name, params object[] args)
{
    return Activator.CreateInstance(this.GetType().Assembly.FullName, name, args);
}
0 голосов
/ 23 апреля 2011
 switch(input)
 {
      case optionA:
          return Activator.CreateInstance(typeof(Bla));
      case optionB:
          return Activator.CreateInstance(typeof(Blb));
 }

$ 0,02

Любые дополнительные параметры к конструктору Bla / Blo могут быть добавлены

Activator.CreateInstance(typeof(Bla), 1, 2 ,3);

На самом деле, он принимает массив параметров params.Поэтому, если вам нужно было передать их динамически,

object[] dynparams = new object[] { 1,2, "more", 4.5, new List<int>() };
...
return Activator.CreateInstance(typeof(Bla), dynparams);

Существует множество других перегрузок, прочитайте о них здесь

Теперь я не знаю ни одного из ваших названий типов,но вы сможете сделать

Object obj = Activator.CreateInstance(null, "Namespace1.MyClass1", dynparams);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...