为什么转储此 JObject 会在 LINQPad 中引发 AmbiguousMatchException?
Why does dumping this JObject throw an AmbiguousMatchException in 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();
尝试将已解析的 JSON 转储到 LINQPad 的输出 window 时抛出 AmbiguousMatchException
。为什么?据我所知,这是完全合法的 JSON。 http://jsonlint.com/ 也说有效。
这很可能是 .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
The current Type represents a type that implements the same generic interface with different type arguments.
所以看起来 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如何试图找出最好的问题将对象转储到输出的方法 window.
当我在 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();
尝试将已解析的 JSON 转储到 LINQPad 的输出 window 时抛出 AmbiguousMatchException
。为什么?据我所知,这是完全合法的 JSON。 http://jsonlint.com/ 也说有效。
这很可能是 .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
The current Type represents a type that implements the same generic interface with different type arguments.
所以看起来 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如何试图找出最好的问题将对象转储到输出的方法 window.