【发布时间】:2019-01-03 09:23:59
【问题描述】:
我终于制作了一个重现此错误的最小示例:
using System;
using Newtonsoft.Json;
class Program
{
public byte[] Foo(byte[] p) { return new byte[0]; }
public byte[] Foo(Guid? p) { return new byte[0]; }
static Guid? ToGuid(string s) { return s == null ? null : (Guid?)new Guid(s); }
void Bar()
{
dynamic d = JsonConvert.DeserializeObject<dynamic>("{}");
var id = d?.id?.ToString();
Foo(ToGuid(id));
}
static void Main(string[] args)
{
new Program().Bar();
}
}
奇怪的是,当 d.id 为空(或不是字符串)时,它在运行时调用 Foo 时崩溃,说它无法解析要调用的 Foo 版本(以下方法或属性之间的调用不明确)。为什么这不是在编译时解决的呢? dynamic 不应该有什么不同,我可以看到,事实上更奇怪的是,如果我在 ToGuid... 之前添加一个显式强制转换“(Guid?)”,它会按预期工作,同样如果我把它写成:
Guid? id = ToGuid(d.id?.ToString());
Foo(id)
这实际上更有意义。如果我将“var”更改为“string”,它也可以正常工作。
我注意到异常最初是从“System.Linq.Expressions.dll”引发的,这有点奇怪。完整的堆栈跟踪基本上是:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:以下方法或属性之间的调用不明确:“FooService.Foo(byte[])”和“FooService.Foo(System.Guid?)” 在 CallSite.Target(Closure , CallSite , FooService , Object )
异常来源是“匿名托管的 DynamicMethods 程序集”
【问题讨论】:
-
你不是在
Guid? ToGuid(string s) { return uuid == null ? null : new Guid(uuid) }收到编译错误Type of conditional expression cannot be determined because there is no implicit conversion between '<null>' and 'System.Guid'吗? -
已修复,抱歉...
-
那是因为你的例子没有使用动态。只有当 ToGuid( ) 的参数最终来自动态类型变量时才会发生这种情况。
-
但该站点似乎使用了非常旧的 C# 版本,甚至不允许我写
d?.id.ToString()(这似乎是关键部分)。我正在使用 7.1 -
可以复制。您的代码在
d中传递,id为 null 或任何可以完美运行的代码。
标签: c#