【发布时间】:2011-09-12 09:58:34
【问题描述】:
当我有以下类并尝试使用DataContractSerializer.WriteObject(..) 序列化ConcreteClass 实例时,我得到一个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:类型 AbstractClass' 不能被序列化。考虑用 DataContractAttribute 属性,并标记您的所有成员 想要使用 DataMemberAttribute 属性进行序列化。见 其他受支持类型的 Microsoft .NET Framework 文档。
如果我离开无参数构造函数并使用建议的属性,它甚至可以工作。那么为什么会有区别以及为什么要尝试序列化抽象类呢?当然,抽象类中可能有属性之类的东西,但它们不应该与 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);
}
}
}
【问题讨论】:
-
您打算如何实例化
abstract class?逻辑错误,不计算。 -
我不打算那样做。当我写“添加
public AbstractClass() {}”时,我的意思是将这行代码添加到AbstractClass的代码中 -
你找到答案了吗?
-
@Omaer 不是真的,除了明显的(在基类中没有带参数的构造函数,使基类中的字段至少受保护且非只读,然后从子构造函数。)
-
@user764754 我最终切换到 Json.Net 只是为了解决这个问题......谢谢!
标签: c# serialization constructor abstract-class datacontractserializer