繁体   English   中英

C# 序列化一个没有无参数构造函数的类

[英]C# serialize a class without a parameterless constructor

我正在为 3 个不同的密码学类实现工厂模式。 工厂将决定创建哪一个,然后从数据库中获取正确类的序列化实例并将其返回给请求者。 现在我正在对类进行序列化以将它们存储在数据库中。 我正在为名为BouncyCastle的 PGP 密码学类编写一个。 我可以从文件创建类和键,但是当我尝试对其进行序列化时,它说两个成员变量,即PgpPublicKeyPgpPrivateKey类的对象,无法序列化,因为它们没有无参数构造函数。

public void createdBouncyFromFiles()
{
    var bc = new BouncyCastle("C:\\TestFiles\\BouncyPublicKey.txt", "C:\\TestFiles\\BouncyPrivateKey.txt", "Password1");
    var xmlSerializer = new XmlSerializer(bc.GetType());
    var textWriter = new StringWriter();
    xmlSerializer.Serialize(textWriter, bc);
    var theSerializedClass = textWriter.ToString();
}

该类有两个成员变量是问题所在。

public class BouncyCastle : ICryptographyProvider
{

    public PgpPublicKey m_publicKey;
    public PgpPrivateKey m_privateKey;
    public string m_passPhrase;
    // cut out the irelevant parts

这是公钥类。 没有无参数的构造函数。

public class PgpPublicKey
{
    public PgpPublicKey(PublicKeyAlgorithmTag algorithm, AsymmetricKeyParameter pubKey, DateTime time);
    // cut other methods
}

任何序列化器类都需要一个无参数构造函数,因为在反序列化它时会创建一个空的新实例,然后它会复制从序列化数据中获取的每个公共属性。

如果您想避免在没有参数的情况下创建它,您可以轻松地将构造函数设为私有。

前任:

public class PgpPublicKey
{
    public PgpPublicKey(PublicKeyAlgorithmTag algorithm, AsymmetricKeyParameter pubKey, DateTime time);

    private PgpPublicKey();
    // cut other methods
}

是的,XmlSerializer需要存在无参数构造函数才能使序列化工作。

来自以下答案: Why XML-Serializable class need a parameterless constructor

在对象的反序列化期间,负责反序列化对象的类创建序列化类的实例,然后仅在获取要填充的实例后才继续填充序列化的字段和属性。

如果需要,您可以将构造函数设为私有或内部,只要它是无参数的。

DataContractSerializer 不需要无参数构造函数。 相反,它需要的是类的特殊属性。

PgpPublicKeyPgpPrivateKey类是否由您定义? 只需向它们添加无参数构造函数即可。

如果您不想从外部访问它们,它们可以是私有的。 解串器仍然可以访问它们。

对于几年后仍在寻找的人来说,现在的答案是 FormatterServices.GetUninitializedObject。 小心它,因为这只是一块设置为所有空值和零的内存,如果对象默认值中的字段不是零,则可能设置错误:“因为对象的新实例已初始化为零并且没有运行构造函数,则该对象可能不代表该对象认为有效的状态。”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM