本文介绍了防止基类序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得我应该知道这一点,但出于某种原因......

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).

例如:

// 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);
        }
    }
}

正如所写,这将抛出 SerializationException,因为 SomeBaseClass 未标记为可序列化.

As written, this will throw a SerializationException because SomeBaseClass isn't marked as serializable.

推荐答案

简短回答:使用组合而不是继承.将要序列化的成员提取到另一个类中并使其可序列化.这将使您能够控制生命周期和序列化的范围.

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.

一般来说,将序列化对象作为哑数据持有者并通过包装它们添加任何附加逻辑是一种很好的模式.现代序列化框架(如 protobuf、thrift、avro)加强了这一点,它们无论如何都会为您生成这些序列化对象背后的代码,并希望您不要通过继承来破坏这些类的内部结构.

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.

这篇关于防止基类序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 02:44