0

我正在尝试XmlSerializer从 C# 中使用来保存一个类,该类具有一些由属性读取的值(代码只是对字段值的简单检索)但由 setter 函数设置(因为如果值更改,则会调用一个委托)。

我目前正在做的就是这种事情。预期用途是使用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了。

我似乎通过以这种方式区分属性集和设置器函数来遵循标准做法,所以我确定我不是唯一遇到过这种情况的人(尽管谷歌建议我可能是)。在这种情况下,其他人做了什么?有没有一些简单的方法可以说服他们XmlSerializer更好地处理这类事情?如果没有,是否有其他简单的方法可以做到这一点?

4

1 回答 1

1

编辑:
我真的只是将 setter 函数作为属性的一部分。如果你愿意,你可以让 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);
    }
}
于 2010-03-15T19:53:26.557 回答