Как я могу динамически вызывать конструктор в C #? - PullRequest
5 голосов
/ 17 марта 2009

Я использую LINQ-to-XML для запроса файла со списком объектов. Все они имеют одинаковую структуру (заданное количество опций, список параметров неопределенной длины). Основываясь на их имени в XML-файле, я хочу использовать параметры для совершенно разных вещей - поэтому я создал подклассы этого объекта.

У меня вопрос: как динамически вызвать правильный конструктор, не делая что-то вроде оператора case? Или решение элегантной реализации различных подклассов из XML лежит в другом месте?

class Object1
{
    string name;
    OptionObj opt;
    List<Param> parameters;
}

class sonOfObject : Object1
{
    public void ExecuteSomething()
    {
         //do something with the parameters
    }
}

class secondSonOfObject : Object1
{
    public void ExecuteSomething()
    {
         //do something entirely different with the parameters
    }
}

var query = from x in xmlDoc.Descendants("Object")
    select new Object
    {
        //select the object from the XML
    }

После этого куска кода я мог бы использовать конструктор копирования, чтобы сделать sonOfObject из более общего объекта запроса. Но как мне сделать это динамически, основываясь на имени дочернего класса?

Я знаю, что вы можете получить MethodInfo из типа и вызвать его ala ...

MethodInfo m = t.GetMethod(someName);
m.Invoke(yourObj, null);

Но это означало бы, что я должен был бы создать 9 или 10 таких дочерних объектов класса (и получить тип для каждого из них), и все равно оказаться в неком выражении case

Есть ли более элегантный способ динамического вызова конструкторов дочерних классов?

Ответы [ 2 ]

7 голосов
/ 17 марта 2009

Activator.CreateInstance позволяет передать имя класса в виде строки и вернет вам новый экземпляр этого класса.

3 голосов
/ 17 марта 2009

Чтобы класс мог участвовать в этой схеме, я бы пометил его пользовательским атрибутом, который дает ему «имя XML».

Затем используйте отражение, чтобы найти все Type, отмеченные этим атрибутом, и поместите их в Dictionary<string, Type>. На этом этапе вам нужно решить, как вы будете искать другие сборки, которые могут вносить типы в систему. Простой подход заключается в поиске других файлов с расширением .DLL в том же каталоге.

Затем, когда у вас есть строка из XML, которую вы хотите использовать для создания экземпляра соответствующего Type, просто найдите Type в Dictionary по имени и вызовите Type.GetConstructor и ConstructorInfo.Invoke .

Преимущество этого заключается в том, что идентификатор в XML отделен от физического макета вашего кода - вы можете перемещать типы в сборках или переименовывать их, не аннулируя старые файлы XML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...