使用动态参数的方法重载解析 [英] Method overload resolution using dynamic argument
问题描述
这可能已经回答过了。我看到很多动态方法重载的问题,但没有与传递动态
参数专门处理。在下面的代码中,测试
,到 M
解决不了的最后一次通话(它不编译)。该错误是:呼叫[的 M中的前两个重载
]之间
暧昧。
静态无效M(Func键< INT&F)的温度{}
静态无效M(Func键<字符串&F)的温度{}
静态无效M(Func键<动态&F)的温度{}
静态动态DynamicObject(){
返回新的对象();
}
静态无效测试(){
M(()= 0);
M(()=>中);
M(()=> DynamicObject()); //不能编译
}
- 为什么,因为该类型不是静态已知的,它不能解决过载接受
动态
? - 它甚至有可能一个重载的方法使用
动态
? - 什么是解决这个最好的方法?
这里的问题是类型推断。编译器试图找出超载基础上的说法来使用,但它也试图找出什么参数的类型是根据所选择的过载。在 M(()=> DynamicObject())的情况下
,这个过程是这样的:
- 来该方法的参数是零参数的lambda。这给我们的所有三个重载的可能性。
- 拉姆达回报的主体
动态
。因为从动态
任何其他类型的隐式转换,我们现在知道的所有三个重载都不错。 - 尝试选择最好的超载。在大多数情况下,最佳是指最派生类型。因为无论
INT
和字符串
从对象
,重载派生与INT
和字符串
被认为是最好的。 - 我们现在有两个最好的重载,这意味着编译器实际上不能选择其中之一。该编译失败
现在,关于您的问题可能的解决方案:
-
请拉姆达的类型明确,或者使用铸造或类型的局部变量:
M((Func键&所述;动态>)(()=> DynamicObject()));
或
Func键<动态> F =()=> DynamicObject();
M(F);
-
重命名动态重载类似
DynamicM
。 。这样,您就不必处理重载 -
这一个人感到有点错误的我:确保
动态
超载是千篇一律,通过转换成对象
只有一个:M(()=>(对象)DynamicObject())
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?
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:
- The argument to the method is a lambda with zero parameters. This gives us all three overloads as possibilities.
- The body of the lambda returns
dynamic
. Because there is an implicit conversion fromdynamic
to any other type, we now know all three overloads are good. - Try choosing the best overload. In most cases, "best" means the most derived type. Because both
int
andstring
derive fromobject
, the overloads withint
andstring
are considered best. - We now have two "best" overloads, which means the compiler can't actually choose one of them. The compilation fails.
Now, regarding possible solutions to your problem:
Make the type of the lambda explicit, either using cast or typed local variable:
M((Func<dynamic>)(() => DynamicObject()));
or
Func<dynamic> f = () => DynamicObject(); M(f);
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
:M(() => (object)DynamicObject())
这篇关于使用动态参数的方法重载解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!