我有一个有很多'可选bools'的类 - 布尔值可能是true,false或null。在.NET中表示这种情况的最常见方式是使用bool?
,但是在内存中占用至少2个字节(请参阅this question),因此我编写了自己的OptionalBool
结构只占用1个字节,可以隐式转换为bool?
。
我的问题是,我有一个这样的课程:
public class PartnerLoginOptions
{
public string Username { get; set; }
public string Password { get; set; }
public string DeviceModel { get; set; }
public string Version { get; set; }
public OptionalBool IncludeUrls { get; set; }
public OptionalBool ReturnDeviceType { get; set; }
public OptionalBool ReturnUpdatePromptVersions { get; set; }
}
如何在序列化时让Json.NET执行从OptionalBool
到bool?
的implcit转换?例如,如果IncludeUrls
为default(OptionalBool)
(即'null'),ReturnDeviceType
为真且ReturnUpdatePromptVersions
为false,则输出的JSON看起来像
{
"includeUrls": null,
"returnDeviceType": true,
"returnUpdatePromptVersions": false
}
如果有PartnerLoginOptions
个对象,我怎么能这样做?我到目前为止的代码是
var body = JsonConvert.SerializeObject(options, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
修改:如果它有用,here是OptionalBool
的源代码。
答案 0 :(得分:4)
回答您的问题,您可以执行以下操作:
public class PartnerLoginOptions
{
public string Username { get; set; }
public string Password { get; set; }
public string DeviceModel { get; set; }
public string Version { get; set; }
[JsonIgnore]
public OptionalBool IncludeUrls { get; set; }
[JsonProperty("IncludeUrls")]
public bool? IncludeUrlsConverted
{
get { return (bool?)IncludeUrls; } // your conversion here
set { IncludeUrls = (OptionalBool)value; } // your backwards conversion here
}
}
或者您可以自己编写JsonConverter
。
然而,对我而言,OptionalBool
看起来像是一个过度工程师。
2个字节绝对不多,我无法想象真正需要它的情况,同时它会产生很多不兼容问题,产生转换器和不同的黑客,并降低可读性。
请考虑更改为bool?
。
答案 1 :(得分:1)
如果您真的想这样做,可以为OptionalBool
定义自定义转换器:
public class OptionalBoolConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(OptionalBool) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var converted = (bool?) (OptionalBool) value;
writer.WriteValue(converted);
}
}
然后以这种方式使用它:
var test = new PartnerLoginOptions
{
ReturnDeviceType = true,
ReturnUpdatePromptVersions = false
};
var json = JsonConvert.SerializeObject(test, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new JsonConverter[] {new OptionalBoolConverter()}
});