仅对序列化和反序列化声明的属性类型的最简单方法是什么,忽略了实际对象的派生比声明更多的事实?例如,使用这些类:
[DataContract]
public class Base
{
[DataMember]
string BaseProperty { get; set; }
}
public class Derived : Base
{
string DerivedProperty { get; set; }
}
我希望能够达到相同的目的:
Base baseObject = new Derived();
var baseSerializer = new DataContractSerializer(typeof(Base));
using (var fileStream = File.OpenWrite("file"))
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(fileStream))
{
baseSerializer.WriteObject(writer, baseObject);
}
using (var fileStream = File.OpenRead("file"))
using (var reader = XmlDictionaryReader.CreateBinaryReader(fileStream, new XmlDictionaryReaderQuotas()))
{
var deserialized = (Base)baseSerializer.ReadObject(reader);
}
提供示例代码失败,因为Derived
当然不是已知类型。但是我不想将这些额外的信息写入文件,只是基类提供的信息。
答案 0 :(得分:3)
此解决方案使用反射来获取基类的属性,并在派生类值上设置基类值的新实例。它解决了您当前的问题,但可能无法解决所有问题。
祝你好运,这就是编程的乐趣,我相信你必须修改一些!
[DataContract]
public class Base
{
[DataMember]
string BaseProperty { get; set; }
public void SetBase(string val)
{
BaseProperty = val;
}
}
public class Derived : Base
{
public Derived()
{
SetBase("TestWorks");
}
string DerivedProperty { get; set; }
}
static void Main(string[] args)
{
var obj = new Derived();
Base baseObject = GetBaseObject<Base, Derived>(obj);
var baseSerializer = new DataContractSerializer(typeof(Base));
using (var fileStream = File.OpenWrite("file"))
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(fileStream))
{
baseSerializer.WriteObject(writer, baseObject);
}
using (var fileStream = File.OpenRead("file"))
using (var reader = XmlDictionaryReader.CreateBinaryReader(fileStream, new XmlDictionaryReaderQuotas()))
{
var deserialized = (Base)baseSerializer.ReadObject(reader);
}
}
public static TBase GetBaseObject<TBase, T>(T obj) where TBase : new() where T : TBase
{
TBase bObj = new TBase();
var bProps = bObj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
foreach (var bProp in bProps)
{
bProp.SetValue(bObj,
obj.GetType().BaseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
.First(p => p.Name == bProp.Name).GetValue(obj));
}
return bObj;
}