Использование .NET XmlSerializer со свойствами get и функциями установки - PullRequest
0 голосов
/ 15 марта 2010

Я пытаюсь использовать XmlSerializer из C #, чтобы сохранить класс, который имеет некоторые значения, которые считываются свойствами (код является простым извлечением значения поля), но устанавливаются функциями-установщиками (поскольку существует вызывается делегат, если значение изменяется).

То, что я сейчас делаю, это такие вещи. Предполагаемое использование - использовать свойство InT для чтения значения и использовать SetInT для его установки. Установка его имеет побочные эффекты, поэтому метод более уместен, чем свойство здесь. XmlSerializationOnly_InT существует исключительно в интересах XmlSerializer (отсюда и название) и не должен использоваться нормальным кодом.

class X
{
    public double InT
    {
        get { return _inT; }
    }

    public void SetInT(double newInT)
    {
        if (newInT != _inT)
        {
            _inT = newInT;
            Changed();//includes delegate call; potentially expensive
        }
    }

    private double _inT;

    // not called by normal code, as the property set is not just a simple
    // field set or two.
    [XmlElement(ElementName = "InT")]
    public double XmlSerializationOnly_InT
    {
        get { return InT; }
        set { SetInT(value); }
    }
}

Это работает, это достаточно просто сделать, и файл XML выглядит так, как вы и ожидаете. Хотя это ручной труд, и немного некрасиво, так что я только немного доволен. Что я действительно хотел бы, так это уметь указывать XML-сериализации читать значение с помощью свойства и устанавливать его с помощью функции setter. Тогда мне вообще не понадобится XmlSerializationOnly_InT.

Кажется, я следую стандартной практике, проводя различие между наборами свойств и функциями сеттера таким образом, поэтому я уверен, что я не единственный, кто сталкивался с этим (хотя Google предполагает, что я мог бы быть). Что другие сделали в этой ситуации? Есть ли какой-нибудь простой способ убедить XmlSerializer лучше справиться с подобными вещами? Если нет, то, возможно, есть какой-то другой простой способ сделать это?

1 Ответ

1 голос
/ 15 марта 2010

EDIT:
Я бы на самом деле просто сделал функцию setter частью свойства. Если вы хотите, вы можете заставить установщик вызвать событие и вызвать функцию в событии.

// A delegate type for hooking up change notifications.
public delegate void ChangedEventHandler(object sender, EventArgs e);

class X
{
    private double _inT;

    // An event that clients can use to be notified whenever the
    // elements of the list change.
    public event ChangedEventHandler InTChanged;
    // Invoke the Changed event; called whenever list changes

    protected virtual void OnChanged(EventArgs e) 
    {
        if (InTChanged != null)
            InTChanged(this, e);
    }
    public double InT
    {
        get { return InT; }
        set
        {
            _inT = newInT;

            //Invoke InTChanged event here
            OnChanged(EventArgs.Empty);
        }
    }
}

В противном случае вы могли бы просто исправить свои собственные функции сериализации и десериализации:

class X
{
    public void SetInT(double newInT)
    {
        if (newInT != _inT)
        {
            _inT = newInT;
            Changed();//includes delegate call; potentially expensive
        }
    }

    private double _inT;

    public double InT
    {
        get { return InT; }
    }
    public XElement SerializeX()
    {
        XElement serializedItems = new XElement("X",
            new XElement("InT", this._inT),
            new XElement("OtherProperty1", this.OtherProperty1),
            new XElement("OtherProperty2", this.OtherProperty2));
        return serializedItems;
    }
    public void DeserializeX(XElement itemXML)
    {
        this._inT = Double.Parse(itemXML.Element("InT").Value,
            CultureInfo.InvariantCulture);
        this.OtherProperty1 = Double.Parse(
            itemXML.Element("OtherProperty1").Value,
            CultureInfo.InvariantCulture);
        this.OtherProperty2 = Double.Parse(
            itemXML.Element("OtherProperty2").Value,
            CultureInfo.InvariantCulture);
    }
}
...