我刚刚发现了这个有趣的问题:
int done = 50;
int? total = 100;
var perc = done * 100 / total; // No problem
// Error: Argument 2: cannot convert from 'int?' to 'byte'
// Argument 1 is still int32
var perc2 = Math.Min(100, done * 100 / total);
起初,我的代码只需要第一个perc
。令人惊讶的是,那里没有错误,因为我错过了应该在那里的null
检查。我直到后来才发现我的错误:
然后在某些情况下,估计值total
比它应该的值小得多,但百分比需要限制在100,所以我添加了Math.Min
。现在我发现我错过了一个空检查,错误消息有点误导。
这里发生了什么?C#在这种情况下试图做什么?
2条答案
按热度按时间nukf8bse1#
当你在代码中调用一个方法时,编译器会试图找到你传递的参数列表(如果有的话)提供的方法。
你可以使用
M(42)
调用它,一切正常。当有多个候选者时:编译器将应用“重载解析”来确定“适用的函数成员”,并且当多个时,编译器将计算重载的“更好”以确定您打算调用的“更好的函数成员”。
在上面的例子
M(42)
中,选择int
重载是因为C#中非后缀的数字字面量默认为int
,所以M(int)
是“更好”的重载。(All“引号”中的部分可以在C#语言规范12.6.4重载解决方案中查找。
现在到你的代码。
假设文字
100
可以存储在byte
和int
中(然后是一些),并且您的第二个参数不匹配任何一个重载,编译器不知道您打算调用哪个重载。它必须选择任何一个来向您显示错误消息。在本例中,它似乎选择了声明顺序中的第一个。
给定此代码:
其中提到:
无法从“int?”转换为“int”
如果我们交换方法声明:
它抱怨说:
无法从“int?”转换为“byte”
vm0i2vca2#
你正在使用一个Nullable类型。这是一种对不能为null的结构的 Package 。要获取值,你需要引用它: