gpt4 book ai didi

c# - 避免默认构造函数和公共(public)属性 setter

转载 作者:行者123 更新时间:2023-12-03 18:48:01 25 4
gpt4 key购买 nike

我正在使用 SignalR 进行一个项目,我有一些对象要通过它传递。这些对象仅在我的后端代码中显式创建,我真的很希望能够对它们实现不变性和不变性。我遇到了一个问题,SignalR 要求我(好吧,真的是 NewtonSoft.Json)在我的属性上有一个默认的、无参数的构造函数和公共(public) setter ,以便它通过网络对它们进行序列化和反序列化。

这是一个人为的例子:

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

我想要的是更多类似的东西(它可能应该有只读私有(private)字段和 getter-only 属性以完全不可变,但对于只是一个没有方法的 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 表示中分离出“真实”对象并在它们之间进行转换,但我真的不想写一堆样板来做到这一点并引入另一个层。

我是否忽略了什么,或者我只需要硬着头皮处理它?<​​/p>

最佳答案

如果您的类没有公共(public)无参数构造函数,但有一个带参数的公共(public)构造函数,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 成功地序列化和反序列化您的类。

原型(prototype) fiddle .

如果你的类有多个公共(public)构造函数,都带有参数,你可以标记一个使用 [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 是否更喜欢非公共(public)无参数构造函数而不是带有参数的单个公共(public)构造函数。

关于c# - 避免默认构造函数和公共(public)属性 setter ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35245256/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com