【发布时间】:2018-08-29 07:47:36
【问题描述】:
考虑以下最小示例:
class Program {
static void Main(string[] args) {
Dictionary<string, int> obj = GetDynamic() ?? new List<string>();
}
private static dynamic GetDynamic() {
return null;
}
}
代码将编译,但在运行时失败,因为 List<T> 无法转换为 Dictionary<TKey, TValue>。我猜这是因为表达式GetDynamic() ?? new List<string>() 在编译时解析为dynamic。
当空合并运算符的任一操作数与预期的返回类型不匹配时,有没有办法强制编译错误?
【问题讨论】:
-
您不能强制默认编译器在此处引发错误消息。但我想您可以开发自己的 Roslyn 扩展来生成自定义错误消息。以前没有做过类似的事情,所以我只能建议谷歌搜索“c# roslyn extension”或类似的东西。
-
这已经发生了。真正的问题是
dynamic总是可以转换为其他东西,尽管隐式转换可能在运行时失败。这里没有(编译时)输入错误。当然,您可以强制使用:(Dictionary<string, int>) GetDynamic() ?? new List<string>()——但这需要您知道dynamic参与其中。我能想到的所有其他解决方法都涉及更多,并且需要人为地重写??,除非您已经知道该问题(这违背了目的),否则您不会在实际代码中使用它们。 -
如果你已经知道返回的类型,为什么还要使用
dynamic?将dynamic更改为Dictionary<string, int>,您将获得所需的编译时错误。如果您不知道返回的类型,那么您的代码设计有缺陷,当它返回除Dictionary<string, int>以外的任何内容时,您将收到运行时错误。 -
@RacilHilan 这显然是一个学术问题。
GetDynamic可能第三方 API 方法 OP 无法更改。问题的重点是“类型安全”:如何在编译时避免这种错误。 -
该示例是从使用
dynamic进行配置的旧版应用程序中提取的。我只是在应用程序中偶然发现了这样一个错误,并想知道为什么编译器无法判断这里有什么问题(因为这对开发人员来说非常明显)。
标签: c# .net type-safety null-coalescing-operator