Вопрос

Я пытаюсь сериализовать объект в XML, который имеет ряд свойств, некоторые из которых доступны только для чтения.

public Guid Id { get; private set; }

Я пометил класс [Serializable] и реализовал интерфейс ISerializable.

Ниже приведен код, который я использую для сериализации моего объекта.

public void SaveMyObject(MyObject obj)
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
    TextWriter tw = new StreamWriter(_location);
    serializer.Serialize(tw, obj);
    tw.Close();
}

К сожалению, это сообщение заканчивается на первой строке.

Исключение InvalidOperationException не было обработано:Не удалось сгенерировать временный класс (результат=1).ошибка CS0200:Свойство или индексатор 'MyObject.Идентификатор' не может быть присвоен - он доступен только для чтения

Если я установлю для свойства Id значение public, оно будет работать нормально.Может ли кто-нибудь сказать мне, делаю ли я что-то, или, по крайней мере, возможно ли это вообще?

Это было полезно?

Решение

Вы могли бы использовать DataContractSerializer (но обратите внимание, что вы не можете использовать xml-атрибуты - только xml-элементы):

using System;
using System.Runtime.Serialization;
using System.Xml;
[DataContract]
class MyObject {
    public MyObject(Guid id) { this.id = id; }
    [DataMember(Name="Id")]
    private Guid id;
    public Guid Id { get {return id;}}
}
static class Program {
    static void Main() {
        var ser = new DataContractSerializer(typeof(MyObject));
        var obj = new MyObject(Guid.NewGuid());
        using(XmlWriter xw = XmlWriter.Create(Console.Out)) {
            ser.WriteObject(xw, obj);
        }
    }
}

В качестве альтернативы, вы можете реализовать IXmlSerializable и делайте все сами - но это работает с XmlSerializer, по крайней мере.

Другие советы

Вы могли бы использовать System.Runtime.Serialization.NetDataContractSerializer.Он более мощный и устраняет некоторые проблемы классического Xml-сериализатора.

Обратите внимание, что для этого существуют разные атрибуты.

[DataContract]
public class X
{
  [DataMember]
  public Guid Id { get; private set; }
}


NetDataContractSerializer serializer = new NetDataContractSerializer();
TextWriter tw = new StreamWriter(_location);
serializer.Serialize(tw, obj);

Редактировать:

Обновление, основанное на комментарии Марка:Вероятно, вам следует использовать System.Runtime.Serialization.DataContractSerializer для вашего случая необходимо получить чистый XML-файл.Остальная часть кода такая же.

Поля, доступные только для чтения, не будут сериализованы с помощью XmlSerializer, это связано с характером readonly ключевое слово

Из MSDN:

Тот Самый только для чтения ключевое слово - это модификатор, который вы можете использовать для полей.Когда объявление поля включает модификатор только для чтения, присвоения полям, введенным объявлением, могут выполняться только как часть объявления или в конструкторе того же класса.

Итак...вам в значительной степени нужно было бы установить значение полей в конструкторе по умолчанию...

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

По сути, отметьте свойство public, но генерирует исключение, если к нему обращаются в любое время, отличное от десериализации.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top