使用DataContractSerializer序列化重写属性

4

我在基类中有一个抽象属性,被两个派生类覆盖。其中一个派生类需要将该属性序列化,而另一个则不需要:

[Serializable]
[DataContract(IsReference = true)]
public abstract class Component
{
    public abstract bool IsSelected { get; set; }   
}

[Serializable]
[DataContract]
public class Leaf : Component
{
    [DataMember]
    public override bool IsSelected { get; set; }   // serialized
}

[Serializable]
[DataContract]
public class Composite : Component
{
    private List<Component> componentList = new List<Component>();

    /// <summary>
    /// Should *not* be serialized
    /// </summary>
    public override bool IsSelected
    {
        get
        {
            foreach (Component component in componentList)
            {
                if (!component.IsSelected)
                    return false;
            }

            return true;
        }
        set
        {
            foreach (Component component in componentList)
                component.IsSelected = value;
        }
    }
}

我认为在Leaf的'IsSelected'属性上放置[DataMember]属性就足够了,但显然,甚至Leaf的属性都没有被序列化。

谢谢!


你为什么同时应用Serializable和DataContract? - Prabhu Murthy
2个回答

1
我在Reflector中研究了这个问题,查看了System.Runtime.Serialization的4.0.0.0版本,发现生成序列化契约的代码明确忽略了从某个基类覆盖的属性。因此,在您的示例中,运行时明确且故意不序列化Leaf.IsSelected
我怀疑之所以这样做是因为他们不想处理基类(或某个中间祖先类)是否也将序列化该属性的检查。如果是这种情况,你可能会得到多个序列化的属性值,这可能是不可取的。
像往常一样,我们不应过度依赖Reflector显示的内容,因为代码总是可以改变的,但至少我们知道它是有意这样行事的。
如果其他人也在寻找,那么代码就是ClassDataContract.ClassDataContractCriticalHelper中的ImportDataMembers函数。

0

您需要在CompositeComponent类的IsSelected属性上同时添加[DataMember]属性。尝试一下吧。


但我不希望Composite序列化任何东西! - alhazen
你为什么关心Composite.IsSelected是否被序列化? - Josh C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接