避免使用默认的构造方法和公共属性设置方法 - c#

我正在使用SignalR进行一个项目,并且我要通过这些对象。这些对象只是在我的后端代码中显式创建的,我真的很希望能够对它们强制执行不变性和不变性。我遇到了SignalR要求我(实际上是NewtonSoft.Json)要在我的属性上具有默认的无参数构造函数和公共设置程序的问题,以便它可以通过电线对它们进行序列化和反序列化。

这是一个人为的示例:

public class Message{
    public string Text {get;set;}
    public int Awesomeness {get;set;}
}

我想要的是更多类似的东西(它应该具有只读的私有字段和仅具有getter的属性,以使其完全不可变,但是对于只是没有方法的POCO来说,已经足够好了)

public class Message {
    public string Text {get;private set;}
    public int Awesomeness {get;private set;}
    public Message( string msg, int awesome){
        if (awesome < 1 || awesome > 5){
            throw new ArgumentOutOfRangeException("awesome");
        }
        Text = msg;
        Awesomeness = awesome;
    }
}

但是,如果这样做,SignalR .NET客户端库将无法反序列化我的对象。我可以在其中插入一个默认的构造函数,并将我的setter公开,但是然后我必须记住不要在我的代码中使用它们,并确保团队中没有其他人在不理解的情况下使用它们。

我已经开始执行此操作,将默认构造函数标记为永远不应显式使用的东西:

[Obsolete("Bad! don't do this!")
public Message(){}

但是我不能仅在属性的setter上使用Obsolete属性。

如果我真的愿意,我可以从DTO表示中分离出“真实的”对象并在它们之间进行转换,但是我并不真的很想写一堆样板来实现这一点并引入另一层。

有什么我要忽略的,还是我只需要硬着头皮处理一下?

参考方案

如果您的类没有公共的无参数构造函数,但是有一个带有参数的公共构造函数,则Json.NET将调用该构造函数,并使用反射将构造函数参数与JSON属性进行匹配,并使用反射并为缺失的属性使用默认值。按名称匹配不区分大小写,除非有多个匹配仅在大小写不同的情况下匹配,在这种情况下,匹配变得区分大小写。因此,如果您只是这样做:

public class Message
{
    public string Text { get; private set; }
    public int Awesomeness { get; private set; }
    public Message(string text, int awesomeness)
    {
        if (awesomeness < 1 || awesomeness > 5)
        {
            throw new ArgumentOutOfRangeException("awesome");
        }
        this.Text = text;
        this.Awesomeness = awesomeness;
    }
}

您将能够使用Json.NET成功地序列化和反序列化您的类。

原型fiddle。

如果您的类具有多个带有参数的公共构造函数,则可以将其标记为与[JsonConstructor]一起使用,例如:

public class Message
{
    public string Text { get; private set; }
    public int Awesomeness { get; private set; }

    public Message(string Text)
        : this(Text, 1)
    {
    }

    [JsonConstructor]
    public Message(string text, int awesomeness)
    {
        if (awesomeness < 1 || awesomeness > 5)
        {
            throw new ArgumentOutOfRangeException("awesome");
        }
        this.Text = text;
        this.Awesomeness = awesomeness;
    }
}

另请参见JsonSerializerSettings.ConstructorHandling,它告诉Json.NET是否比带有参数的单个公共构造函数更喜欢非公共的无参数构造函数。

在Sublime Text 3插件中获取当前行 - python

我正在为Sublime Text 3写一个简单的插件,需要获取当前所选行的内容。我可以用selection = sublime.Region(self.view.sel()[0].begin(), self.view.sel()[0].end()) 获取当前突出显示的部分,但是有没有一种方法可以选择或返回整个当前行的内容,而无需手动选择全部?this pag…

Sublime Text-断点时的Python环境 - python

有没有一种方法可以在Sublime Text中配置该功能(例如,存在于PyCharm上),使您可以在代码中具有当前变量上下文的断点时使用python解释器控制台? (我知道您可以获得PDB控制台,但是我指的是功能完善的python控制台解释器)最好。 参考方案 它有一些debuggers,但是看起来很老旧而且很笨拙。当前只有与PyCharm进行免费,全面的比…

System.Text.Json合并两个对象 - c#

是否可以用System.Text.Json?合并两个这样的json对象对象1{ id: 1 william: "shakespeare" } 对象2{ william: "dafoe" foo: "bar" } 结果对象{ id: 1 william: "dafoe" foo: …

Sublime Text 3 Linter问题 - javascript

上周,我发现了这个很棒的文本编辑器“ Sublime Text 3”,我喜欢这些插件。除了SublimeLinter插件和为其添加语言特定棉絮的插件,其他所有东西都可以正常工作。我在与PHP和JavaScript配合使用时遇到问题:PHP确实可以工作,但是我不知道如何使JavaScript正常工作。对于php,我所做的是转到Pref> pac set&…

无法在Sublime Text 3中使用Anaconda解释器 - python

我想将Sublime Text 3用作我的Python编辑器,但无法弄清楚如何使Anaconda成为Python的默认解释器。为了确保将Anaconda正确添加到路径,请在我键入的终端中  $哪个蟒蛇码头退货  / home / rahit / anaconda3 / bin / python但是当我在ST 3中键入这样的代码时import sys prin…