首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查明是否在DeSerialization进程中调用了属性设置器

查明是否在DeSerialization进程中调用了属性设置器
EN

Stack Overflow用户
提问于 2011-11-07 22:44:14
回答 7查看 4.1K关注 0票数 10

有没有办法找出对象属性是否作为DeSerialization过程的一部分被调用(例如,由XmlSerializationReaderXXX调用)。

背景:典型的场景是在这种情况下禁用事件和复杂操作,直到初始化完成。

我发现的一种方法是“解释”堆栈,并检查调用是否由XmlSerializationReaderXXX触发,这不是那么优雅的IMHO。还有更好的吗?

代码语言:javascript
复制
public SomeClass SomeProperty
    {
        get { ..... }
        set
        {
            this._somePropertyValue = value;
            this.DoSomeMoreStuff(); // Do not do this during DeSerialization
        }
    }

-更新--

正如塞尔瓦托提到的,在某种程度上类似于How do you find out when you've been loaded via XML Serialization?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-11-07 23:19:10

我有一个可能的解决方案。

代码语言:javascript
复制
public class xxx
{
    private int myValue;

    [XmlElement("MyProperty")]
    public int MyPropertyForSerialization
    {
        get { return this.myValue; }
        set
        {
            Console.WriteLine("DESERIALIZED");
            this.myValue = value;
        }
    }

    [XmlIgnore]
    public int MyProperty
    {
        get { return this.myValue; }
        set
        {
            Console.WriteLine("NORMAL");
            this.myValue = value;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        xxx instance = new xxx();

        instance.MyProperty = 100; // This should print "NORMAL"

        // We serialize

        var serializer = new XmlSerializer(typeof(xxx));

        var memoryStream = new MemoryStream();
        serializer.Serialize(memoryStream, instance);

        // Let's print our XML so we understand what's going on.

        memoryStream.Position = 0;
        var reader = new StreamReader(memoryStream);
        Console.WriteLine(reader.ReadToEnd());

        // Now we deserialize

        memoryStream.Position = 0;
        var deserialized = serializer.Deserialize(memoryStream) as xxx; // This should print DESERIALIZED

        Console.ReadLine();
    }
}

诀窍是使用XmlIgnore,它将强制xml序列化程序忽略我们的属性,然后我们使用XmlElement将序列化的属性重命名为我们想要的属性的名称。

这种技术的问题是,您必须公开一个公共属性来进行序列化,这在某种程度上是不好的,因为它实际上可以被每个人调用。不幸的是,如果成员是私人的,它将不起作用。

它可以工作,不是完全干净的,但它是线程安全的,不依赖于任何标志。

另一种可能是使用类似于Memento模式的东西。使用相同的技巧,您可以添加一个名为example Memento的属性,该属性返回另一个包含仅适用于序列化的属性的对象,它可以使事情变得更简洁。

你有没有想过不改变方法而使用DataContractSerializer?它的功能要强大得多,并且生成纯XML。它支持OnDeserializationCallback机制。

票数 4
EN

Stack Overflow用户

发布于 2011-11-07 22:50:21

因为你有一个非常复杂的场景,你可能想要考虑创建一个“数据核心”类,它将使用简单的直接方式被序列化/反序列化。然后,您的复杂对象是从该对象构造的,您可以照常触发所有事件/操作。它将使反序列化->触发事件/操作序列更加明确且更易于理解。

票数 2
EN

Stack Overflow用户

发布于 2011-11-07 22:50:31

有一对OnDeserializingAttribute/OnDeserializedAttribute属性。您可以在反序列化对象时设置isDeserializing标志。不过,我不知道它们是否能很好地处理XML序列化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8038020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档