1

当 aushort?被传递给Assert.Equal它时,它试图将两个参数转换为string。它适用于int?. 如果我将代码更改为ushort test = 10;or Assert.Equal((ushort)10, test);Assert.Equal(10, (ushort)test);它工作正常。这是什么原因?可能是因为ushortand both charis 2 bytes 并且Assert.Equal隐含地试图将其ushort?视为字符串吗?

在此处输入图像描述

4

1 回答 1

3

请注意,虽然存在从10to的隐式转换ushort?

ushort? foo = 10;

这只适用于常量表达式10在 的范围内ushort,并且应用了隐式常量表达式转换


Equal方法组具有通用方法,例如您尝试调用的方法。所以在重载决议开始之前,类型推断发生了。

类型推断作为方法调用的绑定时处理的一部分发生,并且发生在调用的重载解决步骤之前。如果在方法调用中指定了特定方法组,并且没有将类型参数指定为方法调用的一部分,则类型推断将应用于方法组中的每个泛型方法。[...] 如果特定方法的类型推断失败,则该方法不参与重载决议。

在这种情况下,所有泛型重载的类型推断实际上都失败了,因此它们不参与重载决策。Equal(string, string)是重载之一。这就是错误消息与字符串重载有关的原因。

为什么类型推断会失败?因为没有从inttoushort?或 from ushort?to的隐式转换int。类型推断只关心参数、形参和类型参数的类型。它不关心参数是常量表达式还是类似的东西,所以前面提到的隐式常量表达式转换不适用。我鼓励您遵循规范中的类型推断过程。很有趣 :)

请参阅此处对“类型Ei”的引用:

对于每个方法参数Ei

  • [...]
  • 否则,如果Ei具有类型 U并且是值参数,则从toxi进行下限推断。UTi
  • [...]

将此与它在重载解析中引用“参数”而不是“参数类型”的方式进行比较:

对于 中的每个实A参,实参的传参方式(即值、refout)与对应形参的传参方式相同,且

  • 对于值形参或形参数组,存在从实参到对应形参类型的隐式转换,或
  • [...]

因此,重载决议似乎确实会查看参数的表达式,这就是为什么如果您将方法设为非泛型并接受两个ushort?. 在那种情况下,它不参与类型推断,只参与重载决议。

强制转换10toushort或起作用的原因是,在 from to和 from tobyte之间确实存在隐式转换。这是通过隐式可空转换完成的。ushortushort?byteushort?

于 2020-12-02T05:56:08.080 回答