你說得對,因爲Newtonsoft.Json不會很好地對待Lookup<TKey, TElement>
。下面的代碼:
var input = new List<string>()
{
"A1",
"A2",
"B1",
"C1",
"C2"
};
var lookup = input.ToLookup(i => i[0], i => i);
var json = JsonConvert.SerializeObject(lookup);
Console.WriteLine(json);
序列化爲:
[["A1","A2"],["B1"],["C1","C2"]]
你正確地注意到(A
,B
,C
)缺少關鍵的名稱,它似乎被序列化爲一個數組的數組。
似乎不支持序列化外觀查找,所以你必須編寫自己的轉換器。
我找到了一個here,但這要求您事先知道密鑰類型和值。
修改它,這樣做的工作:
// Same as above, up till here
var json = JsonConvert.SerializeObject(lookup, new LookupSerializer());
Console.WriteLine(json);
}
}
public class LookupSerializer : JsonConverter
{
public override bool CanConvert(Type objectType)
{
var result = objectType.GetInterfaces().Any(a => a.IsGenericType
&& a.GetGenericTypeDefinition() == typeof(ILookup<,>));
return result;
}
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 obj = new JObject();
var enumerable = (IEnumerable)value;
foreach (object kvp in enumerable)
{
// TODO: caching
var keyProp = kvp.GetType().GetProperty("Key");
var keyValue = keyProp.GetValue(kvp, null);
obj.Add(keyValue.ToString(), JArray.FromObject((IEnumerable)kvp));
}
obj.WriteTo(writer);
}
}
輸出:
{
"A": ["A1", "A2"],
"B": ["B1"],
"C": ["C1", "C2"]
}