具有动态函数参数的 C# 编译器类型推断

标签 c# var type-inference

当我调用函数并将其中一个参数替换为动态时,编译器将函数结果推断为动态。我不明白为什么会这样。

示例:a 的推断类型是动态的,因此此代码可以编译,但当然会在运行时因 RuntimeBinderException 而失败:

dynamic b = "";
var a = MethodWithoutOverloads("", b);
a.DoesNotExist();

...

public string MethodWithoutOverloads(string a, string b) { ... }

有人知道为什么推断出的类型不是函数的返回类型吗?

编辑:编辑以明确这种情况发生在没有重载的方法中

最佳答案

从编译器可以推断出所有 String.Format 重载返回一个 string 并因此推断出 a 必须是一个字符串,无论 b 到底是什么。

事实是编译器不会那样做。它解决了一般情况,这很好,并且由于具有不同返回类型的重载在 C# 中是有效的,它只是将返回类型分配为动态类型并让运行时自行解决。

回答您的具体问题,

public string MethodWithoutOverloads(string a, string b) { ... }
dynamic a = "";
var result = MethodWithoutOverloads(a, a); // result is dynamic.

让我们想象一下,编译器决定 resultstring 并且您将您的库发布到狂野的西部。然后,稍后,您决定添加具有以下签名的重载:

public int MethodWithoutOverloads(int a, int b) { ... } 

现在,result 的类型应该是什么?而且,依赖于 result 被强类型化为 string 的现有代码会怎样?

string result = MethodWithoutOverloads(someDynamicVariable, someOtherDynamicVariable);

语义完全改变;在消费者拥有安全的强类型变量之前,现在他突然拥有一个可能在运行时爆炸的潜在不安全隐式转换。

关于具有动态函数参数的 C# 编译器类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42435001/

相关文章:

c++ - 为什么此模板参数推断失败?

c# - 从视频文件中提取wav文件

Javascript:如何在 if block 内提升(或不提升)let?

c# - 将 "var"转换为 Visual Studio 中的显式类型?

c# - 在 Visual Studio 中查看 var 的类型

generics - F# 泛型方法和运算符

scala - 使用多态函数作为参数

c# - Azure Active Directory 应用服务无法使用用户凭据/ token 连接到 Azure Keyvault

c# - 使用 C# 在 Datagridview 中绘制统计图

c# - "The specified network password is not correct"在没有密码的证书上,仅在实时服务器上