是否有可能将JSON反序列化到一个属性名可能是两个值之一的类中?
例如,这两个json将反序列化为相同的属性:
var json1 = "{"A":5}";
var json2 = "{"B":5}";
我想也许我可以使用JsonPropertyName属性两次。
[JsonPropertyName("A")]
[JsonPropertyName("B")]
public int SomeInt { get; set; }
这是不允许的
然后我想,如果反序列化器找不到JsonPropertyName属性,它可能会寻找实际的属性名称。
[JsonPropertyName("A")]
public int B { get; set; }
但这也不行。
你可以有两个独立的属性,一个委托给另一个:
[JsonPropertyName("A")]
[Obsolete("Explain why here")]
public int A
{
get => B;
set => B = value;
}
[JsonPropertyName("B")]
public int B { get; set; }
缺点是在序列化时将写入和。我最初认为您可以使用JsonIgnoreAttribute
作为过时的属性,但这也会阻止它被反序列化:(如果您仅将其用于解析,则不太糟糕,但如果您也要序列化,则不太愉快。
另外,如果使用这两个参数解析JSON文件,最后设置的那个将胜出,这可能不是理想的。
我没有足够的声誉来评论Jon Skeet的回答,但是可以稍微修改一下,使用一个backing属性来避免两次写入。
[JsonPropertyName("A")]
[Obsolete("Explain why here")]
public int? A
{
get => B;
set => B = value;
}
private int? _b;
[JsonPropertyName("B")]
public int? B
{
get { return _b; }
set
{
if (_b == null)
_b = value;
}
}
当对JSON进行反序列化时,我将使用一个可空的int,因为可能没有值。
如果必须使用int类型,则可以检查成员变量是否为default。缺点是如果你真的想让0代表0,如果第一个值是0并且它们都存在于文件中,那么它将被第二个值覆盖。
[JsonPropertyName("A")]
[Obsolete("Explain why here")]
public int A
{
get => B;
set => B = value;
}
private int _b;
[JsonPropertyName("B")]
public int B
{
get { return _b; }
set
{
if (_b == default)
_b = value;
}
}