我有一个具有许多'可选bools'的类 - 可能是真实,false或null的布尔值。在.NET中表示这一点的最常见方法是使用bool?
,但是在内存中至少占用了2个字节(请参阅此问题),因此我编写了自己的OptionalBool
struct,该结构仅占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
为true, ReturnUpdatePromptVersions
是错误的,那么输出的JSON看起来像
{
"includeUrls": null,
"returnDeviceType": true,
"returnUpdatePromptVersions": false
}
我该如何给定一个PartnerLoginOptions
对象?我到目前为止的代码是
var body = JsonConvert.SerializeObject(options, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
编辑:如果有用,这是OptionalBool
的源代码。
回答您的问题,您可以执行以下操作:
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?
。
如果您真的想这样做,则可以为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()}
});