使用DataContractSerializer序列化overriden属性

时间:2012-09-26 17:30:55

标签: c# .net inheritance datacontractserializer composite

我在基数中有一个absract属性,被2个派生类覆盖。我希望为其中一个属性序列化,而不是另一个:

[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的属性都没有被序列化。

谢谢!

2 个答案:

答案 0 :(得分:1)

我在Reflector中挖掘了这个,查看了System.Runtime.Serialization的4.0.0.0版本,看起来生成序列化契约的代码明确地忽略了从某个基类重写的属性。因此,运行时明确且故意不在您的示例中序列化Leaf.IsSelected

我怀疑它是这样做的,因为他们不想处理检查基类(或某些中间祖先类)是否也将序列化属性。如果是这种情况,您最终可能会被序列化的属性的多个值,这可能是不可取的。

一如既往,我们不应过分依赖Reflector所展示的内容,因为代码总是会改变,但至少我们知道它有意这样做。

如果有其他人在查找,则代码是ImportDataMembers中的ClassDataContract.ClassDataContractCriticalHelper函数。

答案 1 :(得分:0)

您还需要在复合组件类的 IsSelected 属性中添加[DataMember]属性。试试吧。