2009-10-25 5 views
0

У меня есть объект InputFile, который имеет массивы и объекты для хранения содержимого файла. У меня также есть ABCFile и XYZFile, которые унаследованы от InputFile, которые будут читать разные типы файлов и хранить их в проецируемых элементах InputFile.XML Deserialization of Inherited Objects

Поскольку сериализация и десериализация обоих этих объектов идентичны родительскому объекту, я реализовал стандартный интерфейс сериализации XML на родительском объекте. Во время десериализации считывается несколько параметров, вызывается функция Read (для загрузки файла), затем завершается десериализация.

сериализации отлично работает, но десериализации (из List<InputFile>) не работает, потому что десериализатор называет родители окурок Read файл функции вместо ABCFile или XYZFile «с.

Как я могу получить десериализацию, чтобы распознать правильный тип объекта для использования? Возможно, что у моего List<InputFile> будет множество типов файлов.

Благодаря

код я использую для сериализации объекта:

public class InputFileHolder : IXmlSerializable { 
... 
public void WriteXml(XmlWriter w) { 
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
    ns.Add("", ""); 

    XmlSerializer ifXml = new XmlSerializer(typeof(List<InputFile>)); 
    ifXml.Serialize(w, InputFiles, ns); 

    //More serialization 
} 

Любые идеи, как сохранить тип объекта, когда я пользовательских сериализации список?

ответ

7

Попробуйте

[XmlArray] 
[XmlArrayItem(ElementName="ABCFile", Type=typeof(ABCFile))] 
[XmlArrayItem(ElementName="XYZFile", Type=typeof(XYZFile))] 
public List<InputFile> InputFileList 
{ 
    get; 
    set; 
} 

Это будет означать, что сериалайзер, даже если это является Список InputFile, там будет два производных типов, которые будут храниться в этом списке. Вероятно, он использует определенную версию методов для каждого из них.

Если это не удается, сообщите мне.

Редактировать основанный на ваш комментарий

Я не вижу, как это может быть happing.

Я проверил это следующие классы:

public class InputFile 
{ 
    public String InputfileCommonProperty { get; set; } 
} 

public class ABCFile : InputFile 
{ 
    public String ABCSpecificProperty { get; set; } 
} 

public class XYZFile : InputFile 
{ 
    public String XYZSpecificProperty { get; set; } 
} 

public class InputFileHolder 
{ 
    public InputFileHolder() 
    { 
     InputFileList = new List<InputFile>(); 
    } 

    [XmlArray] 
    [XmlArrayItem(ElementName = "ABCFile", Type = typeof(ABCFile))] 
    [XmlArrayItem(ElementName = "XYZFile", Type = typeof(XYZFile))] 
    public List<InputFile> InputFileList { get; set; } 
} 

Моя главная программа выглядит следующим образом:

static void Main(string[] args) 
{ 
    InputFileHolder fileHolder = new InputFileHolder(); 
    fileHolder.InputFileList.Add(
     new ABCFile() 
     { 
      InputfileCommonProperty = "This is a common property", 
      ABCSpecificProperty = "This is a class specific property" 
     }); 

    XmlSerializer serializer = new XmlSerializer(typeof(InputFileHolder)); 
    MemoryStream memoryStream = new MemoryStream(); 
    serializer.Serialize(memoryStream, fileHolder); 

    System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); 
    String serializedString = enc.GetString(memoryStream.ToArray()); 
} 

И в конце концов, содержание serializedString является:

<?xml version="1.0"?> 
<InputFileHolder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <InputFileList> 
    <ABCFile> 
     <InputfileCommonProperty>This is a common property</InputfileCommonProperty> 
     <ABCSpecificProperty>This is a class specific property</ABCSpecificProperty> 
    </ABCFile> 
    </InputFileList> 
</InputFileHolder> 

Вы видите? Сериализатор знает, что это ABCFile не общий InputFile.

+0

Благодарим за быстрый ответ. Созданный XML по-прежнему выглядит так: . Если я вручную отредактировал XML, чтобы изменить InputFile на ABCFile, он не работает с ошибкой XML. – Aaron

+0

Взгляните на мой фрагмент кода и скажите, что произойдет –

+0

Хорошо, думаю, я обнаружил корень проблемы. Моя версия InputFileHolder имеет интерфейс IXmlSerializable, где у меня есть пользовательское чтение/запись параметров для сериализации.Если я удалю интерфейс IXmlSerializable и дам инфраструктуре обработать его, я получаю XML как ваш, где указан тип объекта. Мне нужно иметь пользовательское чтение, поэтому мне нужно исправить запись. Я напишу свой код в главном сообщении. – Aaron