将JSON反序列化为具有私有构造函数和只读属性的类在C#中

huangapple go评论79阅读模式
英文:

Deserialize json into class with private constructor and readonly properties in C#

问题

I am using .NET的System.Text.Json来将JSON反序列化为不可变类。我想要隐藏该类的构造函数,以防止用户创建该类的实例,只能在反序列化时创建实例。如何使System.Text.Json使用非默认的私有构造函数?

我想要做类似这样的操作:

public class Sheet
{
    public string Id { get; }
    public IEnumerable<IEnumerable<SheetCell>> Data { get; }

    [JsonConstructor]
    private Sheet(string id, IEnumerable<IEnumerable<SheetCell>> data)
    {
        Id = id;
        Data = data;
    }
}
英文:

I am using .NET's System.Text.Json to deserialize json into an immutable class. I want to hide the constructor from the class user to prevent creating instances of this class and only create instances when deserializing. How can I make System.Text.Json use private constructor which is not default?

I want to do something like this:

public class Sheet
    {
        public string Id { get; }
        public IEnumerable&lt;IEnumerable&lt;SheetCell&gt;&gt; Data { get; }

        [JsonConstructor]
        private Sheet(string id, IEnumerable&lt;IEnumerable&lt;SheetCell&gt;&gt; data)
        {
            Id = id;
            Data = data;
        }
    }

答案1

得分: 1

以下是您要翻译的内容:

如果您不希望最终用户经常创建您的序列化类实例,您可以使用数据传输对象(DTO)模式来处理。在您的库代码中,您有用于序列化和反序列化的内部类,然后有一个单独的公共类对用户可见。

//在内部用这个类进行序列化和反序列化
internal class SheetDto
{
    public string Id { get; init; }
    public IEnumerable<IEnumerable<SheetCell>> Data { get; init; }
}

//最终用户只能访问这个公共类。
public class Sheet
{
    public string Id { get; }
    public IEnumerable<IEnumerable<SheetCell>> Data { get; }

    private Sheet(SheetDto dto)
    {
        Id = dto.Id;
        Data = dto.Data;
    }

    public static Sheet Deserialize()
    {
        //执行您需要的反序列化逻辑以获取SheetDto
        //如果从文件反序列化,也许这个方法接受文件路径
        var dto = someMethodToDeserialize();
        return new Sheet(dto);
    }
}
英文:

If you don't want the end user to create instances of your serialization class often you can handle that using a data transfer object (DTO) pattern. In your library code you have internal classes for serialization and deserialization, and then you have a separate public class that is exposed to the user.

//use this class internally for serializing and deserializing
internal class SheetDto
{
    public string Id { get; init; }
    public IEnumerable&lt;IEnumerable&lt;SheetCell&gt;&gt; Data { get; init; }
}

//the end user only has access to this public class.
public class Sheet
{
    public string Id { get; }
    public IEnumerable&lt;IEnumerable&lt;SheetCell&gt;&gt; Data { get; }

    private Sheet(SheetDto dto)
    {
        Id = dto.Id;
        Data = dto.Data;
    }

    public static Sheet Deserialize()
    {
        //do whatever deserializtion logic you need to get a SheetDto
        //if deserializing from a file, maybe this method takes in a
        //filepath
        var dto = someMethodToDeserialize();
        return new Sheet(dto);
    }
}

huangapple
  • 本文由 发表于 2023年4月17日 21:12:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76035549-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定