Как XML Сериализовать "Тип"
Как сериализовать "Тип"?
Я хочу сериализовать в XML объект, у которого есть свойство, являющееся типом объекта. Идея состоит в том, что при десериализации я могу создать объект такого типа.
public class NewObject
{
}
[XmlRoot]
public class XmlData
{
private Type t;
public Type T
{
get { return t; }
set { t = value; }
}
}
static void Main(string[] args)
{
XmlData data = new XmlData();
data.T = typeof(NewObject);
try
{
XmlSerializer serializer = new XmlSerializer(typeof(XmlData));
try
{
using (FileStream fs = new FileStream("test.xml", FileMode.Create))
{
serializer.Serialize(fs, data);
}
}
catch (Exception ex)
{
}
}
catch (Exception ex)
{
}
}
Я получаю это исключение:
"Тип ConsoleApplication1.NewObject не ожидался. Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, которые не известны статически".
Где я могу поместить [XmlInclude]? Возможно ли это?
Ответы
Ответ 1
Сериализация XML сериализует только общедоступные поля и значения свойств объекта в поток XML. Сериализация XML не включает информацию о типе. Например, если у вас есть объект Book, который существует в пространстве имен Library, нет гарантии, что он будет десериализован в объект того же типа.
Источник: MSDN: введение XML-сериализации
Ответ 2
Type
класс не может быть сериализован, потому что System.RuntimeType
недоступен для нашего кода, это внутренний тип CLR. Вы можете обойти это, используя вместо этого имя типа:
public class c
{
[XmlIgnore]
private Type t;
[XmlIgnore]
public Type T {
get { return t; }
set {
t = value;
tName = value.AssemblyQualifiedName;
}
}
public string tName{
get { return t.AssemblyQualifiedName; }
set { t = Type.GetType(value);}
}
}
Ответ 3
Вы могли бы реализовать интерфейс IXmlSerializable
и использовать Type.FullName
(вам может понадобиться Type.AssemblyQualifiedName
) для сериализации и Assembly.GetType(string)
для десериализации элемента вашего типа.
Ответ 4
Я закончил преобразование имени типа в строку, чтобы сохранить его в XML.
При десериализации я загружаю все библиотеки DLL и сохраняю имя и тип словаря. Когда я загружаю XML с именем типа, я могу найти имя в ключе словаря и узнать тип, основанный на значении словаря.
Ответ 5
Проблема в том, что тип XmlData.T на самом деле является "System.RuntimeType" (подкласс типа), который, к сожалению, не является общедоступным. Это означает, что нет способа рассказать сериализу, какие типы ожидать. Я предлагаю только сериализовать имя типа или полное имя, как предлагает Джей Базузи.
Ответ 6
Уродливый, но он работает. Создайте класс, который включает в себя тип объекта и сериализованную строку.
ех
Class dummie
{
Type objType;
string xml;
}