您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

三元条件下的隐式转换问题

三元条件下的隐式转换问题

这是C#的两个特征融合的结果。

首先是C#永远不会为您“神奇”一个类型。如果C#必须从一组给定类型中确定“最佳”类型,则它总是选择您提供的一种类型。它从未说过:“您给我的类型都不是最好的类型;由于您给我的选择都是不好的,所以我将挑选一些您没有给我的随机选择。”

第二个是从C#原因 里面外面 。我们不会说“哦,我看到您正在尝试将条件运算符结果分配给ILogger;让我确保两个分支都起作用。” 相反的情况发生了:C#说“让我确定两个分支返回的最佳类型,并验证最佳类型是否可以转换为目标类型。”

第二条规则是明智的,因为 目标类型可能是我们要确定的目标类型。 当您说D d = b ? c : a;清楚目标类型是什么时。但是,假设您打电话给您M(b?c:a)?M可能有一百种不同的重载,每种重载都具有形式参数的不同类型!我们必须确定参数的类型,然后丢弃M的重载,这是不适用的,因为参数类型与形式参数不兼容。我们不会走另一条路。

考虑如果我们采取其他方式会发生什么:

M1( b1 ? M2( b3 ? M4( ) : M5 ( ) ) : M6 ( b7 ? M8() : M9() ) );

假设每个M1,M2和M6都有一百个过载。你是做什么?您是否说好,如果这是M1(Foo),则M2(…)和M6(…)必须都可以转换为Foo。是吗 让我们找出答案。M2的过载是多少?有一百种可能性。让我们看看它们中的每一个是否都可以从M4和M5的返回类型转换而来…好吧,我们已经尝试了所有这些,所以我们找到了一个可以工作的M2。现在M6呢?如果我们发现“最佳” M2与“最佳” M6不兼容怎么办?我们是否应该回溯并继续重试所有100 x 100的可能性,直到找到兼容的对?问题变得越来越严重。

我们 这样做的 原因是lambda,因此涉及lambda的重载解析至少在C#中为NP-HARD。那很不好 我们宁愿不为编译器添加更多的NP- HARD问题来解决

您还可以在该语言的其他位置看到正在运行的第一条规则。例如,如果您说: ILogger[] loggers = new[] { consoleLogger, suppressLogger };您将收到类似的错误;推断的数组元素类型必须是给定类型表达式的 最佳类型 。如果无法从中确定最佳类型,我们不会尝试查找您没有给我们的类型。

类型推断也一样。如果你说:

void M<T>(T t1, T t2) { ... }
...
M(consoleLogger, suppressLogger);

这样就不会推断T为ILogger;这将是一个错误。在提供的参数类型中,T被推断为最佳类型,并且在它们之间没有最佳类型。

有关此设计决策如何影响条件运算符的行为的更多详细信息,请参阅我关于该主题的系列文章

如果您对为什么“从外部到内部”有效的过载解析是NP- HARD感兴趣,请参阅本文

其他 2022/1/1 18:15:26 有258人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶