当我调用一个函数并用dynamic替换其中一个参数时,编译器会将函数结果推断为动态。我不明白为什么会这样。
示例:a的推断类型是动态的,因此此代码编译,但当然在运行时因RuntimeBinderException而失败:
dynamic b = "";
var a = MethodWithoutOverloads("", b);
a.DoesNotExist();
...
public string MethodWithoutOverloads(string a, string b) { ... }
有人知道为什么推断的类型不是函数的返回类型?
编辑:编辑以明确这种情况发生在没有重载的方法
答案 0 :(得分:1)
你是正确的,编译器可以推断所有String.Format
重载返回string
,因此推断a
必须是一个字符串无论b
到底是什么。
事实是编译器不这样做。它解决了一般情况,这很好,并且因为具有不同返回类型的重载在C#中有效,它只是将返回类型指定为动态并让运行时计算出来。
回答您的具体问题,
public string MethodWithoutOverloads(string a, string b) { ... }
dynamic a = "";
var result = MethodWithoutOverloads(a, a); // result is dynamic.
让我们想象一下编译器决定result
是string
并且你向你的图书馆西边发布。然后,稍后,您决定添加具有以下签名的重载:
public int MethodWithoutOverloads(int a, int b) { ... }
现在,result
的类型应该是什么?而且,依赖result
强烈输入string
的现有代码会发生什么?
string result = MethodWithoutOverloads(someDynamicVariable, someOtherDynamicVariable);
语义彻底改变;在消费者拥有一个安全的强类型变量之前,现在他突然有一个可能不安全的隐式强制转换,可能会在运行时爆炸。
答案 1 :(得分:0)
因为编译器不知道将在运行时调用哪个方法。
例如,您可能有两种方法:
int MyMethod(int a)
{
return 5;
}
double MyMethod(string a)
{
return 6.0;
}
您编写以下代码:
dynamic myThing = 5;
var myResult = MyMethod(myThing);
考虑到我们已明确表示myThing
是动态,并且其类型将在运行时确定,我们不知道将调用哪个方法(如果有的话)。因此,我们也不知道返回类型。