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-是的,您的答案是有意义的。同样,可以使用类似的方法将派生类映射到基类。但是,如果它们从不需要序列化派生属性,则可以使用一些快捷方式。