Reputation: 5146
What would be the simplest way of serializing and deserializing the declared types of properties only, ignoring the fact that the actual object is more derived than declared? For instance, with these classes:
[DataContract]
public class Base
{
[DataMember]
string BaseProperty { get; set; }
}
public class Derived : Base
{
string DerivedProperty { get; set; }
}
I would like to be able to achieve the equivalent of this:
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);
}
Provided example code fails because Derived
is not a known type, of course. But I'm not interested in writing that additional information into a file, only what the base class provides.
Upvotes: 1
Views: 1415
Reputation: 156
This solution uses reflection to grab the properties of the base class and sets a new instance of your base class values on the derived class values. It solves your current problem but may not solve all problems.
Best of luck, that is the fun of programming and I'm sure you will have to modify this some!
[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;
}
Upvotes: 3