Почему при сбросе этого объекта JObject возникает исключение AmbiguousMatchException в LINQPad?
Когда я запускаю этот код в LINQPad, используя JSON.NET:
var x = JObject.Parse(
@"{
""data"" : [ {
""id"" : ""bbab529ecefe58569c2b301a"",
""name"" : ""Sample Name"",
""group"" : ""8b618be8dc064e653daf62f9"",
""description"" : ""Sample Name"",
""payloadType"" : ""Geolocation"",
""contract"" : ""a9da09a7f4a7e7becf961865"",
""keepAlive"" : 0
} ]
}");
x.Dump();
AmbiguousMatchException
выбрасывается при попытке вывести проанализированный JSON в окно вывода LINQPad. Зачем? Насколько я могу судить, это вполне законный JSON. http://jsonlint.com/ говорит, что это тоже верно.
1 ответ
Это проблема с тем, как .Dump()
реализовано скорее всего.
Если вы проверите трассировку стека:
at System.RuntimeType.GetInterface(String fullname, Boolean ignoreCase)
at System.Type.GetInterface(String name)
at UserQuery.Main()
...
Мы можем видеть, что метод, бросающий исключение System.RuntimeType.GetInterface
,
System.RuntimeType
является одним из конкретных классов, используемых для представления Type
объекты, когда отражение используется во время выполнения, поэтому давайте проверим Type.GetInterface(String, Boolean)
который имеет это сказать:
AmbiguousMatchException
Текущий тип представляет тип, который реализует один и тот же универсальный интерфейс с различными аргументами типа.
Так выглядит GetInterface
Метод вызывается с типом интерфейса, который реализован более одного раза, с различными T
или аналогичные.
Чтобы вызвать ту же ошибку, просто замените x.Dump();
с этим:
var type = x.GetType().GetInterface("System.Collections.Generic.IEnumerable`1", true);
Это бросит то же исключение.
Вот более простой пример LINQPad, который показывает основную проблему:
void Main()
{
var type = typeof(Problem).GetInterface("System.Collections.Generic.IEnumerable`1", true);
}
public class Problem : IEnumerable<string>, IEnumerable<int>
{
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<string>)this).GetEnumerator();
IEnumerator<string> IEnumerable<string>.GetEnumerator() => Enumerable.Empty<string>().GetEnumerator();
IEnumerator<int> IEnumerable<int>.GetEnumerator() => Enumerable.Empty<int>().GetEnumerator();
}
Этот пример будет выбрасывать точно такое же исключение.
Вывод: нет ничего плохого ни в Json, ни в Json.Net, это проблема того, как LINQPad пытается выяснить лучший способ вывести объект в окно вывода.