简体   繁体   English

防止基类的序列化

[英]Prevent Serialization of Base Class

I feel like I should know this, but for some reason.... 我觉得我应该知道这一点,但出于某种原因....

What is the preferred way to serialize a class that derives from a (perhaps abstract) base class, without having to serialize all the way back up the tree? 序列化从(可能是抽象的)基类派生的类的首选方法是什么,而不必一直序列化备份树? For instance, perhaps you cannot control the class that you are deriving from, but want to use serialization to clone your object (and your object only, not the base). 例如,您可能无法控制从中派生的类,但希望使用序列化来克隆您的对象(仅限您的对象,而不是基础)。

For example: 例如:

// This is a base class that is outside my control, which derives from
// some other base class that I know "nothing" about
public abstract class SomeBaseClass : SomeOtherBaseClass
{
    private string mBaseProperty = "Base Property";
    public string BaseProperty
    {
        get { return mBaseProperty; }
        set { mBaseProperty = value; }
    }
}

// This is the class that I do control
[Serializable()]
private class MyDerivedClass : SomeBassClass
{
    // Assume normal constructors, etc.

    // Here are some properties
    private string mDerivedPropertyOne = String.Empty;
    private string DerivedPropertyOne
    {
        get { return mDerivedPropertyOne ; }
        set { mDerivedPropertyOne = value; }
    }

    private string mDerivedPropertyTwo = String.Empty;
    private string DerivedPropertyTwo
    {
        get { return mDerivedPropertyTwo ; }
        set { mDerivedPropertyTwo = value; }
    }

    // And now a quick-n-dirty Equals override
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            MyDerivedClass compareTo = obj as MyDerivedClass;
            if (compareTo == null)
                return false;

            return ((String.Compare(this.DerivedPropertyOne, 
                                    compareTo.DerivedPropertyOne, true) == 0) &&
                    (String.Compare(this.DerivedPropertyTwo, 
                                    compareTo.DerivedPropertyTwo, true) == 0) &&
        }
}

// And while we're at it, here's a simple clone found elsewhere on StackOverflow
public static class ObjectClone
{
    public static T Clone<T>(this T source)
    {
        if (!typeof(T).IsSerializable)
        {             
            throw new ArgumentException("The type must be serializable.", "source");         
        }          

        // Don't serialize a null object, simply return the default for that object         
        if (Object.ReferenceEquals(source, null))
        {             
            return default(T);         
        }          

        IFormatter formatter = new BinaryFormatter();         
        Stream stream = new MemoryStream();         
        using (stream)         
        {             
            formatter.Serialize(stream, source);
            stream.Seek(0, SeekOrigin.Begin);             
            return (T)formatter.Deserialize(stream);         
        }         
    }
}

As written, this will throw a SerializationException because SomeBaseClass isn't marked as serializable. 如上所述,这将抛出SerializationException,因为SomeBaseClass未标记为可序列化。

Short answer: use composition not inheritance. 简答:使用组合而不是继承。 Extract the members you want to serialize into another class and make that one serializable. 将要序列化的成员解压缩到另一个类中,并使其可序列化。 This will give you the control you want over the lifecycle and the extent of the serialization. 这将为您提供生命周期内所需的控件以及序列化的范围。

In general, it's a good pattern for serialized objects to be dumb data holders and have any additional logic added by wrapping them. 一般来说,对于序列化对象来说,它是一个很好的模式,可以作为哑数据持有者,并通过包装它们来添加任何额外的逻辑。 This is reinforced with modern serialization frameworks like protobuf, thrift, avro, which will generate the code behind these serialized objects for you anyway and expect you not to muck with the internals of those classes through inheritance. 现代序列化框架如protobuf,thrift,avro强化了这一点,无论如何都将为这些序列化对象生成代码,并期望你不要通过继承来破坏这些类的内部。

您可以在您的... BaseClass中使用XmlRoot(“MyDerivedClass”)属性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM