【问题标题】:C# serialize a class without a parameterless constructorC#序列化一个没有无参数构造函数的类
【发布时间】:2013-02-19 03:51:08
【问题描述】:

我正在为 3 个不同的加密类实现工厂模式。工厂将确定创建哪个类,然后从数据库中获取正确类的序列化实例并将其返回给请求者。 现在我正在序列化这些类以将它们存储在数据库中。我正在为名为@9​​87654321@ 的 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
}

【问题讨论】:

  • 制作你自己的数据类来序列化,根据需要复制值
  • 为什么不想只添加无参数构造函数?

标签: c# serialization bouncycastle


【解决方案1】:

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

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

前:

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

    private PgpPublicKey();
    // cut other methods
}

【讨论】:

  • 我尝试了私有无参数构造函数,但它对我不起作用。我需要公开它才能正确反序列化
【解决方案2】:

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

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

在对象的反序列化过程中,负责处理的类 反序列化对象会创建序列化类的实例 然后继续填充序列化的字段和属性 仅在获取要填充的实例之后。

如果你愿意,你可以将你的构造函数设为私有或内部,就这样 只要它是无参数的。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      PgpPublicKeyPgpPrivateKey 类是您定义的吗?只需向它们添加无参数构造函数。

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-23
          • 1970-01-01
          • 2010-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多