使用动态参数的方法重载决策
这可能之前已经回答过。我看到很多“动态方法重载解析”问题,但没有一个专门处理传递动态参数。在以下代码中,在 Test
中,无法解析对 M
的最后一次调用(无法编译)。错误是:调用在 [M
的前两个重载] 之间不明确。
static void M(Func<int> f) { }
static void M(Func<string> f) { }
static void M(Func<dynamic> f) { }
static dynamic DynamicObject() {
return new object();
}
static void Test() {
M(() => 0);
M(() => "");
M(() => DynamicObject()); //doesn't compile
}
- 既然类型不是静态已知的,为什么它不能解析为接受
动态
的重载? - 重载方法是否有可能使用
dynamic
? - 解决这个问题的最佳方法是什么?
This may have been answered before. I see many "dynamic method overload resolution" questions, but none that deal specifically with passing a dynamic
argument. In the following code, in Test
, the last call to M
cannot be resolved (it doesn't compile). The error is: the call is ambiguous between [the first two overloads of M
].
static void M(Func<int> f) { }
static void M(Func<string> f) { }
static void M(Func<dynamic> f) { }
static dynamic DynamicObject() {
return new object();
}
static void Test() {
M(() => 0);
M(() => "");
M(() => DynamicObject()); //doesn't compile
}
- Why, since the type isn't statically known, does it not resolve to the overload accepting
dynamic
? - Is it even possible for an overloaded method to use
dynamic
? - What is the best way to resolve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里的问题是类型推断。编译器试图根据参数找出要使用的重载,但它也试图根据所选重载找出参数的类型。对于
M(() => DynamicObject())
,该过程如下所示:dynamic
。因为存在从dynamic
到任何其他类型的隐式转换,所以我们现在知道所有三个重载都是好的。int
和string
均派生自object
,因此使用int
和string
进行重载被认为是最好的。现在,关于您的问题的可能解决方案:
使用强制转换或类型化局部变量使 lambda 的类型显式化:
或
将动态重载重命名为
DynamicM
之类的名称。这样,您就不必处理重载解析。这对我来说有点不对劲:通过转换为
对象
,确保动态
重载是唯一适合的重载:The problem here is type inference. The compiler is trying to find out which overload to use based on the argument, but it's also trying to find out what the type of the argument is based on the chosen overload. In the case of
M(() => DynamicObject())
, the process goes something like this:dynamic
. Because there is an implicit conversion fromdynamic
to any other type, we now know all three overloads are good.int
andstring
derive fromobject
, the overloads withint
andstring
are considered best.Now, regarding possible solutions to your problem:
Make the type of the lambda explicit, either using cast or typed local variable:
or
Rename the dynamic overload to something like
DynamicM
. This way, you don't have to deal with overload resolution.This one feels somewhat wrong to me: make sure the
dynamic
overload is the only one that fits, by casting toobject
:根据 MSDN 中的定义:
动态
因此编译时不存在dynamic,因为它需要将其转换为destination *type*,这就是为什么无法解析它。什么是目的地类型?
事实上,如果你做了这样的事情:
它完美地按照你想要的方式工作,因为
object
在编译时就已经像类型一样存在,与dynamic
类型不同,它必须被转变。From the definition in MSDN:
dynamic
So dynamic doesn't exist when you compile, cause it needs to convert it into destination *type*, and that's why is not able to resolve it. What is destination type ?
In fact if you do something like this:
It perfectly works as you want, as
object
is present like a type already at compile time, in difference ofdynamic
type which have to be converted.