我有以下习惯
JsonConverter
:
using Microsoft.CodeAnalysis.Text;
using Newtonsoft.Json;
using System;
namespace CSTool.Json
{
public class TextSpanJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(TextSpan);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var str = reader.ReadAsString();
var delim = str.IndexOf('.');
var start = int.Parse(str.AsSpan(1, delim - 1));
var end = int.Parse(str.AsSpan(delim + 2, str.Length - delim - 3));
return TextSpan.FromBounds(start, end);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString());
}
}
}
它应该有助于(反)序列化以下类:
using CSTool.Json;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Newtonsoft.Json;
namespace CSTool.ObjectModel
{
public class RefLocCacheItem
{
public string FilePath { get; private set; }
[JsonConverter(typeof(TextSpanJsonConverter))]
public TextSpan TextSpan { get; private set; }
[JsonConverter(typeof(LinePositionSpanJsonConverter))]
public LinePositionSpan LinePositionSpan { get; private set; }
public RefLocCacheItem()
{
}
public RefLocCacheItem(Location o) : this(o.SourceTree.FilePath, o.SourceSpan, o.GetLineSpan().Span)
{
}
public RefLocCacheItem(string filePath, TextSpan textSpan, LinePositionSpan linePositionSpan)
{
FilePath = filePath;
TextSpan = textSpan;
LinePositionSpan = linePositionSpan;
}
}
}
反序列化代码为:
cached = JsonConvert.DeserializeObject<Dictionary<uint, List<RefLocCacheItem>>>(File.ReadAllText(cacheFile));
相应的序列化代码为:
File.WriteAllText(cacheFile, JsonConvert.SerializeObject(cached, Newtonsoft.Json.Formatting.Indented));
下面是一个json文件示例:
{
"100666494": [],
"100666517": [],
"67111627": [
{
"FilePath": "c:\xyz\\tip\\MySourceFile.cs",
"TextSpan": "[105331..105379)",
"LinePositionSpan": "(2379,51)-(2379,99)"
}
],
"67111628": [
{
"FilePath": "c:\xyz\\tip\\MySourceFile.cs",
"TextSpan": "[136762..136795)",
"LinePositionSpan": "(2953,30)-(2953,63)"
}
],
"100666534": []
}
所以,正如你所看到的,序列化工作得很好。然而,反序列化代码从不调用转换器的
ReadJson
功能。事实上,它根本不起作用!没有失败,但返回的字典包含
RefLocCacheItem
s with
null
文件路径和空文本跨度:
我用的是Json。过去上网很多次,我不明白我现在做错了什么。
我使用的是最新版本13.0.1,但我检查了一些旧版本——同样的事情。所以,这是我的错,但在哪里?
澄清编辑
这个
FilePath
属性未反序列化。这与转换器无关。和转换器-
ReadJson
方法甚至没有被调用!