我觉得我应该知道这一点,但出于某种原因......
序列化从(可能是抽象的)基类派生的类的首选方法是什么,而不必一直序列化备份树?例如,您可能无法控制从中派生的类,但希望使用序列化来克隆您的对象(仅限您的对象,而不是基础)。
例如:
// 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未标记为可序列化。
答案 0 :(得分:9)
简短回答:使用组合而不是继承。将要序列化的成员解压缩到另一个类中,并使其可序列化。这将为您提供生命周期内所需的控制以及序列化的范围。
一般来说,对于序列化对象来说,这是一个很好的模式,它是哑数据持有者,并且通过包装它们可以添加任何额外的逻辑。现代序列化框架如protobuf,thrift,avro强化了这一点,无论如何都会为这些序列化对象生成代码,并期望你不要通过继承来破坏这些类的内部。
答案 1 :(得分:0)
你可以在你的... BaseClass
中使用XmlRoot(&#34; MyDerivedClass&#34;)属性