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

C#序列化没有无参数构造函数的类,c#,serialization,bouncycastle,C#,Serialization,Bouncycastle,我正在为3个不同的加密类实现一个工厂模式。工厂将确定创建哪个类,然后从数据库中获取正确类的序列化实例,并将其返回给请求者。 现在我正在序列化这些类以将它们存储在数据库中。我正在为一个名为BouncyCastle的PGP加密类编写一个。我可以从文件中创建类和键,但当我尝试序列化它时,它会说两个成员变量,即类PgpPublicKey和PgpPrivateKey的对象,无法序列化,因为它们没有无参数构造函数 public void createdBouncyFromFiles() { var

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

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
}

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

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

例:

是的,XmlSerializer需要一个无参数构造函数存在,以便序列化工作

根据以下答案:

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

如果愿意,可以将构造函数设置为私有或内部,仅此而已 只要它是无参数的


PgpPublicKey
PgpPrivateKey
类是否由您定义?只需向它们添加无参数构造函数


如果您不想从外部访问它们,它们可以是私有的。反序列化程序仍然可以访问它们。

DataContractSerializer不需要无参数构造函数。取而代之的是类的特殊属性。

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

创建您自己的数据类以序列化,并根据需要复制值为什么不想只添加无参数构造函数?我尝试了私有无参数构造函数,但它对我不起作用。我需要将其公开,以便正确地反序列化
public class PgpPublicKey
{
    public PgpPublicKey(PublicKeyAlgorithmTag algorithm, AsymmetricKeyParameter pubKey, DateTime time);

    private PgpPublicKey();
    // cut other methods
}