gpt4 book ai didi

c# - DataContractSerializer 需要抽象基类中的无参数构造函数

转载 作者:行者123 更新时间:2023-12-01 19:15:50 24 4
gpt4 key购买 nike

当我有以下类并尝试使用 DataContractSerializer 序列化 ConcreteClass 实例时.WriteObject(..) 我收到一个 InvalidDataContractException

public abstract class AbstractClass
{
protected AbstractClass(string text) { }
}

public class ConcreteClass : AbstractClass
{
public ConcreteClass() : base("text") { }
}

序列化器使用new DataContractSerializer(typeof(ConcreteClass)实例化。

使用XmlSerializer没有任何问题。

现在添加 public AbstractClass() {}

两个序列化器都可以工作。

那么为什么 DataContractSerializer 需要抽象基类具有无参数构造函数? Here据说可以序列化“具有不带参数的构造函数”的类型,这对于 ConcreteClass 来说是正确的。我还向这个必需的构造函数添加了一些代码,并且我认为在序列化过程中不会调用它。

<小时/>

完整的异常说:

System.Runtime.Serialization.InvalidDataContractException : Type AbstractClass' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

如果我保留无参数构造函数并使用建议的属性,它甚至可以工作。那么为什么会有差异以及为什么要尝试序列化抽象类呢?当然,抽象类中可能有诸如属性之类的东西,但这些东西不应该与 ConcreteClass 实例(继承这些东西)一起序列化吗?

编辑:

我的确切代码:

namespace SerilizationTest
{
public abstract class AbstractClass
{
public string StringProperty { get; set; }

//This constructor is required (although never called).
//If not present we get "InvalidDataContractException :
//Type AbstractClass cannot be serialized"
public AbstractClass()
{
Console.WriteLine("We won't see this.");
}

public AbstractClass(string text)
{
StringProperty = text;
}
}

public class ConcreteClass : AbstractClass
{
public ConcreteClass() : base("text") { }
}

class Program
{
static void Main()
{
var serializer = new DataContractSerializer(typeof(ConcreteClass));
var memStream = new MemoryStream();
serializer.WriteObject(memStream, new ConcreteClass());
memStream.Seek(0, SeekOrigin.Begin);
var deserializedObj = (ConcreteClass)serializer.ReadObject(memStream);
Console.WriteLine(deserializedObj.StringProperty);
}
}
}

最佳答案

您得到的异常是,AbstractClass 上没有 [DataContract] 属性。

DataContract 是一个属性,用于标记可序列化的类。如果您使用 DataMember 属性告诉它这样做,则该属性只会包含类中要序列化的属性。

DataMember 属性用于标记可序列化类中需要哪些属性。

此属性可在 System.Runtime.Serialization 中找到;

例如...

public abstract class Bar
{
}

public class Foo : Bar
{
string one { get; set; }
string two { get; set; }
string three { get; set; }
}

如果我尝试序列化我的 Foo 类,那么我会得到你的异常(exception)。因此,如果我将 DataContract 属性添加到 Bar 类中,就像异常所暗示的那样,下次我尝试序列化时,我将得到相同的错误,只是指向代码的另一部分,即 Foo 类本身。我需要做的就是像这样将 DataContract 添加到两者中。

[DataContract]
public abstract class Bar
{
}

[DataContract]
public class Foo : Bar
{
string one { get; set; }
string two { get; set; }
string three { get; set; }
}

现在我们所拥有的将能够创建一个序列化文件。但是,不会有任何信息,因为我们从未告诉 DataContract 要包含哪些内容。为了解决此问题,我们将 DataMember 属性添加到我们要包含的类中的属性中。

[DataContract]
public class Foo : Bar
{
[DataMember]
string one { get; set; }
string two { get; set; }
[DataMember]
string three { get; set; }
}

通过在序列化此类时添加 DataMember 属性,它将仅序列化有关字符串一和字符串三的信息。字符串二不会被包含,因为它没有专门用 DataMember 属性标记。

关于c# - DataContractSerializer 需要抽象基类中的无参数构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6305315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com