c# - 防止基类序列化

标签 c# serialization

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

序列化从(可能是抽象的)基类派生的类的首选方法是什么,而不必一直序列化返回树?例如,也许您无法控制派生自的类,但想使用序列化来克隆您的对象(并且仅克隆您的对象,而不是基类)。

例如:

// 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 未标记为可序列化。

最佳答案

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

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

关于c# - 防止基类序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8580319/

相关文章:

c# - 确定 PDF 是否可搜索

c# - 函数Int32.TryParse(“23.0”)返回false-C#MVC4

java - 用于自定义值序列化的 Jackson 自定义注释

c# - Dictionary<Key, Value> 上 .NET 二进制序列化的奇怪行为

c# - RestSharp 序列化/反序列化命名转换

c# - 当类型移动程序集和命名空间时,protobuf-net 是否允许向后兼容?

c# - 如何在以编程方式与控件交互后防止事件触发?

c# - 流畅的休眠 : how to add an extra attribute to a relationship (aka relationship attribute)

c# - 使用 C#.NET 执行外部 EXE

jquery - Ajax 多个数组不工作