C# 如何使用DataContractSerializer仅序列化/反序列化基类属性?
哪种最简单的方法可以仅序列化和反序列化声明的属性类型,而忽略实际对象比声明的对象派生得多这一事实?例如,对于这些类:C# 如何使用DataContractSerializer仅序列化/反序列化基类属性?,c#,.net,serialization,datacontractserializer,C#,.net,Serialization,Datacontractserializer,哪种最简单的方法可以仅序列化和反序列化声明的属性类型,而忽略实际对象比声明的对象派生得多这一事实?例如,对于这些类: [DataContract] public class Base { [DataMember] string BaseProperty { get; set; } } public class Derived : Base { string DerivedProperty { get; set; } } 我希望能够做到这一点: Base baseObj
[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);
}
提供的示例代码失败,因为
派生的
当然不是已知类型。但是我不想将附加信息写入文件,只想基类提供的信息。此解决方案使用反射来获取基类的属性,并在派生类值上设置基类值的新实例。它可以解决您当前的问题,但可能无法解决所有问题
祝你好运,这是编程的乐趣,我相信你将不得不修改一些
[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;
}
[DataContract]
公共阶级基础
{
[数据成员]
字符串BaseProperty{get;set;}
公共无效收进数据库(字符串val)
{
BaseProperty=val;
}
}
派生的公共类:基
{
公共派生()
{
挫折(“测试工程”);
}
字符串DerivedProperty{get;set;}
}
静态void Main(字符串[]参数)
{
var obj=新派生的();
基本baseObject=GetBaseObject(obj);
var baseSerializer=新的DataContractSerializer(typeof(Base));
使用(var fileStream=File.OpenWrite(“文件”))
使用(var writer=XmlDictionaryWriter.CreateBinaryWriter(fileStream))
{
baseSerializer.WriteObject(writer,baseObject);
}
使用(var fileStream=File.OpenRead(“文件”))
使用(var reader=XmlDictionaryReader.CreateBinaryReader(文件流,新的XmlDictionaryReaderQuotas())
{
var反序列化=(基本)baseSerializer.ReadObject(读取器);
}
}
公共静态TBase GetBaseObject(T obj),其中TBase:new()其中T:TBase
{
TBase bObj=新的TBase();
var bProps=bObj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
foreach(bProps中的var bProp)
{
bProp.SetValue(bObj,
obj.GetType().BaseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
.First(p=>p.Name==bProp.Name).GetValue(obj));
}
返回bObj;
}
您不需要在某个地方添加KnownTypeAttribute
?我知道,只需将Derived
添加到已知类型列表中,就可以实现这一点。但我明确不想这样做。我希望忽略一个事实,即实际对象不是简单的Base
。XmlDictionaryWriter倾向于保存类型信息。只需使用没有默认类型支持的序列化程序,例如JSON。在Newtonsoft.JSON中,您可以指定序列化约定,在该约定中,您可以指定要序列化的内容以及通常不应序列化的内容。使用DataContractSerializer是否重要?否则,您可以尝试使用XmlSerializer,它可以在没有所有额外符号的情况下工作。@user1628733-是的,您的答案是有意义的。同样,可以使用类似的方法将派生类映射到基类。但是,如果它们从不需要序列化派生属性,则可以使用一些快捷方式。