有人可以向我解释为什么如果将动态变量用作方法调用的参数,编译器不会检查函数的返回类型吗?
class Program
{
static void Main(string[] args)
{
// int a = GetAString(1); // Compiler error CS0029 Cannot impilicitly convert type 'string' to 'int'
dynamic x = 1;
int b = GetAString(x); // No compiler error -> Runtime Binder Exception
// int c = (string)GetAString(x); // Compiler error CS0029 Cannot impilicitly convert type 'string' to 'int'
}
static string GetAString(int uselessInt)
{
return "abc";
}
}
答案 0 :(得分:2)
通过使用dynamic
,编译器将在您使用动态参数的任何位置生成调用站点。此调用站点将尝试在运行时解析该方法,如果找不到匹配方法,则会引发异常。
在您的示例中,呼叫网站会检查x
,并发现它是int
。然后,它会查找名为GetAString
的任何方法,它们会使用int
并找到您的方法并生成代码以进行调用。
接下来,它将生成代码以尝试将返回值分配给b
。所有这些仍然在运行时完成,因为使用动态变量使整个表达式需要运行时评估。调用网站会查看是否可以生成代码以将string
分配给int
,因为它不会引发异常。
顺便说一下,您的示例没有多大意义,因为您似乎想要string
分配给int
您的GetAsString
方法甚至返回非数值,所以它永远不会分配给int
。如果你写:
dynamic x = 1;
string b = GetAsString(x);
然后一切都应该有效。
答案 1 :(得分:1)
在一般情况下,候选人不一定像你的一样直截了当。例如,请考虑以下两种方法:
string M(string a) => a;
char[] M(char[] a) => a;
这段代码应该建议什么作为最后一个变量的类型?
dynamic d = SomeExpression();
var s = M(d);
此时,C#的设计者必须做出选择:
dynamic
参数调用的方法的返回值本身也是dynamic
。IEnumerable<char>
)。后一种选择基本上就是您在问题中描述的内容。 C#设计师采用了前一种选择。设计决策的可能原因可能是:
dynamic
,那么您更有可能希望继续在任何相关表达式上使用dynamic
,直到你再次明确选择退出。dynamic
来启用多次发送,所以他们并不想通过包含静态类型的规定来进一步鼓励它。dynamic
的其余部分)并且他们认为另一个选项不值得花费更多的时间或精力。