【问题标题】:Why does dumping this JObject throw an AmbiguousMatchException in LINQPad?为什么转储此 JObject 会在 LINQPad 中引发 AmbiguousMatchException?
【发布时间】:2016-09-02 07:26:54
【问题描述】:

当我使用 JSON.NET 在 LINQPad 中运行此代码时:

var x = JObject.Parse(
@"{
  ""data"" : [ {
    ""id"" : ""bbab529ecefe58569c2b301a"",
    ""name"" : ""Sample Name"",
    ""group"" : ""8b618be8dc064e653daf62f9"",
    ""description"" : ""Sample Name"",
    ""payloadType"" : ""Geolocation"",
    ""contract"" : ""a9da09a7f4a7e7becf961865"",
    ""keepAlive"" : 0
  } ]
}");

x.Dump();

在尝试将解析的 JSON 转储到 LINQPad 的输出窗口时抛出 AmbiguousMatchException。为什么?据我所知,这是完全合法的 JSON。 http://jsonlint.com/ 说它也是有效的。

【问题讨论】:

  • 此问题现已在 LINQPad v5.09.03 中修复

标签: json json.net linqpad linq-to-json


【解决方案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
当前的 Type 表示一个类型,它实现了具有不同类型参数的相同泛型接口。

所以看起来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 试图找出将对象转储到输出窗口的最佳方式的问题。

【讨论】:

  • 嗯好的。那么可能是错误报告时间。我会把它带到 LINQPad 论坛。
  • 我展示了一个较小的示例来显示潜在问题,这将更适合我认为的错误报告,以避免与 Json.net 混淆。也就是说,如果你这样做:new Problem().Dump();,那么除了GetInterface 调用之外,你还有你的错误报告示例,它显示了Dump 的哪个部分有问题。
  • 正确 - 感谢您的诊断。我明天会发布一个 LINQPad 修复。
  • 此问题现已在 LINQPad v5.09.03 中修复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多