0

私はXmlSerializerC#から使用して、プロパティによって読み取られるいくつかの値を持つクラスを保存しようとしています(コードはフィールド値の単純な取得です)が、セッター関数によって設定されます(値が変更された場合に呼び出されるデリゲートがあるため) )。

私が現在行っているのは、このようなことです。使用目的は、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 ファイルは期待どおりに表示されます。手作業ですし、ちょっと見苦しいので、少しだけ満足です。私が本当に望んでいるのは、プロパティを使用して値を読み取り、setter 関数を使用して値を設定するように XML シリアライゼーションに指示できるようにすることです。それなら、私はまったく必要ありませんXmlSerializationOnly_InT

私はこのようにプロパティ セットとセッター関数を区別することで標準的な慣行に従っているように見えるので、これに遭遇したのは私だけではないと確信しています (Google は私がそうかもしれないと示唆していますが)。この状況で他の人は何をしましたか?XmlSerializerこの種のことをより適切に処理するよう説得する簡単な方法はありますか? そうでない場合、おそらく他の簡単な方法はありますか?

4

1 に答える 1

1

編集:
私は本当にセッター関数をプロパティの一部にするだけです。必要に応じて、セッターにイベントをトリガーさせ、イベントで関数を呼び出すことができます。

// 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 に答える