简体   繁体   English

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

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

I'm implementing a factory pattern for 3 different cryptography classes.我正在为 3 个不同的密码学类实现工厂模式。 The factory will determine which one to create and then get a serialized instance of the correct class from a database and return it to the requester.工厂将决定创建哪一个,然后从数据库中获取正确类的序列化实例并将其返回给请求者。 Right now I'm working on serializing the classes to store them in the database.现在我正在对类进行序列化以将它们存储在数据库中。 I'm writing one for a PGP cryptography class called BouncyCastle .我正在为名为BouncyCastle的 PGP 密码学类编写一个。 I can create the class and the keys from files but when I try to serialize it, it says that the two member variables, which are objects of class PgpPublicKey , and PgpPrivateKey , cannot be serialized because they do not have parameterless constructors.我可以从文件创建类和键,但是当我尝试对其进行序列化时,它说两个成员变量,即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();
}

The class has two member variables that are the problem.该类有两个成员变量是问题所在。

public class BouncyCastle : ICryptographyProvider
{

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

This is the public key class.这是公钥类。 No parameterless constructor.没有无参数的构造函数。

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

Any Serializer Class need a parameterless constructor because, while deserializing it create an empty new instance, then it copies every public property taken from seialized data.任何序列化器类都需要一个无参数构造函数,因为在反序列化它时会创建一个空的新实例,然后它会复制从序列化数据中获取的每个公共属性。

You can easily make the constructor private, if you want to avoid to create it without parameters.如果您想避免在没有参数的情况下创建它,您可以轻松地将构造函数设为私有。

EX:前任:

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

    private PgpPublicKey();
    // cut other methods
}

Yes, the XmlSerializer requires a parameterless constructor to exist in order for the serialization to work.是的,XmlSerializer需要存在无参数构造函数才能使序列化工作。

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

During an object's de-serialization, the class responsible for de-serializing an object creates an instance of the serialized class and then proceeds to populate the serialized fields and properties only after acquiring an instance to populate.在对象的反序列化期间,负责反序列化对象的类创建序列化类的实例,然后仅在获取要填充的实例后才继续填充序列化的字段和属性。

You can make your constructor private or internal if you want, just so long as its parameterless.如果需要,您可以将构造函数设为私有或内部,只要它是无参数的。

DataContractSerializer does not require parameterless constructor. DataContractSerializer 不需要无参数构造函数。 What it instead requires are special attributes of class.相反,它需要的是类的特殊属性。

Are PgpPublicKey and PgpPrivateKey classes defined by you? PgpPublicKeyPgpPrivateKey类是否由您定义? Simply add parameterless constructors to them.只需向它们添加无参数构造函数即可。

They can be private if you don't want to make them accessible from outside.如果您不想从外部访问它们,它们可以是私有的。 The deserializer can still access them.解串器仍然可以访问它们。

For anyone who is still looking a few years later, the answer is now FormatterServices.GetUninitializedObject.对于几年后仍在寻找的人来说,现在的答案是 FormatterServices.GetUninitializedObject。 Be careful with it, as this is just a piece of memory set to all nulls and zeros and if a field in the object's default value is something other than zero, it might be set wrong: "Because the new instance of the object is initialized to zero and no constructors are run, the object might not represent a state that is regarded as valid by that object."小心它,因为这只是一块设置为所有空值和零的内存,如果对象默认值中的字段不是零,则可能设置错误:“因为对象的新实例已初始化为零并且没有运行构造函数,则该对象可能不代表该对象认为有效的状态。”

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

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