десериализация XML с динамическими типами / преобразование строки в System.Type - PullRequest
1 голос
/ 05 июня 2009

Хммм Я не уверен, правильно ли я назвал этот вопрос или задаю его правильно, но здесь идет речь.

В базе данных хранятся сериализованные объекты (в формате XML) вместе со строкой / varchar, указывающей тип.

Прямо сейчас я делаю это: (потому что у меня есть конечное число различных типов)

Dim deserializer as XmlSerializer
If datatable("type") = "widget1" then 
     deserializer = new XmlSerializer(GetType(Widget1))
elseif datatable("type") = "widget2" then 
     deserializer = new XmlSerializer(GetType(Widget2))
...

я бы хотел сделать что-то вроде

Dim deserializer as XmlSerializer
deserializer = new XmlSerializer(MagicallyConvertToSystemDotType(datatable("type"))

Я лаю не на том дереве?

Ответы [ 3 ]

2 голосов
/ 05 июня 2009

Вы пробовали использовать Type.GetType? Это принимает строковый параметр и возвращает тип для этого имени. Возможно, вам придется дать ему дополнительную информацию о простом названии «виджет» и многое другое по аналогии с полным именем. Но из вашего примера видно, что все они должны иметь одинаковое пространство имен, чтобы это не было большим препятствием.

0 голосов
/ 26 октября 2009

В частности, я думаю, что вы ищете этот код здесь (ПРИМЕЧАНИЕ: я мало работаю в VB.Net, поэтому я надеюсь, что все там синтаксически правильно):

VB.Net:

// Get the type of object being deserialized.
Dim t as Type = Type.GetType(typeNameString);
// Make a new instance of the object.
Dim o as Object = Activator.CreateInstance(t);

C #:

// Get the type of object being deserialized.
Type t = Type.GetType(typeNameString);
// Make a new instance of the object.
object o = Activator.CreateInstance(t);

Редактировать (26 октября 2009, 15:10 GMT-0600): Метод Type.GetType (string typeNameString) не всегда распознает типы как просто их полное имя. Было бы в ваших интересах быть уверенным и включать как можно больше информации в строку параметров следующим образом:

VB.Net / C #:

typeNameString = objectSerialized.GetType().Namespace + ", " + objectSerialized.GetType().Name + ", " + objectSerialized.GetType().Assembly.FullName

Менее конкретно, у меня просто была та же проблема, и после долгих исследований я наконец-то нашел хорошее решение для обработки всех большинства из этого динамически. Я разместил весь исходный код в классе, способном сериализовать и десериализовывать объекты любого типа , не содержащие обобщенных типов или массивов , с использованием Reflection. Не стесняйтесь взять его и использовать как свой собственный. Если кто-то решит добавить обработку для дженериков и массивов, пришлите мне обновленную копию, чтобы я мог опубликовать ее в своем блоге (и вы получите достойное упоминание; -) ...). Он будет рекурсивно сериализовать все, и там будет специальное кодирование для перечислений.

Взгляните и посмотрите, охватывает ли это все, что вы ищете:

http://maxaffinity.blogspot.com/2009/10/serialize-objects-manually.html

~ md5sum ~

Редактировать (27 октября 2009 14:38 GMT-0600): Исправлена ​​некоторая дезинформация о классе, доступная в моем блоге.

0 голосов
/ 30 сентября 2009

Другой вариант, если вы хотите, чтобы фактическое ключевое слово Type работало, а не переменный тип, использовало что-то вроде (извините, я использую C # и слишком устал для преобразования VB):

method in XmlSerializer like Deserialize(typestring, object);
method in XmlSerializer like Deserialize<T>(object);


public void Deserialize(string typestring, object obj)
{
  MethodInfo deserialize = typeof(XmlSerializer)
      .GetMethod("Deserialize", BindingFlags.Instance | BindingFlags.Public)
      .MakeGenericMethod(new Type[] { Type.GetType(typestring) });
  deserialize.Invoke(this, new[] { obj });
}
...