first_expression和second_expression的类型必须是 相同,或者必须存在从一种类型到另一种类型的隐式转换。
如果文字没有后缀,则它具有第一种类型 它的值可以表示为:int,uint,long,ulong。
考虑:
var value = test ? (Int64)1 : 0;
0,没有后缀的十进制数字文字将转换为int
。 int
可以隐式转换为Int64
。由于此转换仅在一个方向上发生,因此我们可以确定返回值将是Int64。
然而:
var value = test ? (UInt64)1 : 0;
UInt64
和int
无法隐式转换为彼此,但此代码会编译并运行,结果类型为UInt64
。
0
的类型在什么时候确定?
如果两种类型可以隐式地相互转换,那么你最终会选择哪两种类型? (我认为这不会发生,但是用户生成的类可以实现这样的转换。)
之前的研究:
我发现了其他几个类似标题的问题,但它们都与null或可空类型相关。
相关性: 这在我的代码中很重要,因为我们立即将此结果传递给ByteWriter.Write,并希望以正确的重载结束写入正确的字节数。这些例子当然大大简化了。
替代语法使结果显式可能是最清楚的选择,无论实际发生什么没有显式转换:
var value = test ? (UInt64)1 : (UInt64)0;
答案 0 :(得分:3)
请注意,当数字为编译时常量(文字)时,整数类型之间存在一组隐式转换,而当它们不是常量时,则存在另一组转换。
你有趣的例子是:
var value = test ? (UInt64)1 : 0;
也可以写成:
var value = test ? 1ul : 0;
其中ul
后缀表示ulong
,即System.UInt64
。
当使用文字(常量)时,确实存在从int
(System.Int32
)到ulong
的隐式转换,但仅当int
常量为非负时。它真的一样:
const ulong a = 1ul;
const int b = 0;
var value = test ? a : b; // also works fine
正如我所说,它起作用,因为int
(因为编译器知道b
不是负的)到ulong
的隐式常量转换。
现在,取走const
获取:
ulong a = 1ul;
int b = 0;
var value = test ? a : b; // compile-time error, no implicit conversion in either direction!
我们看到,对于非常量,不存在任何方向的隐式转换,因此a
和b
没有最佳公共类型,但这会失败。
答案 1 :(得分:1)
没错,泛型 int
不能隐式转换为UInt
任何长度。但在这里,我们不是在谈论一个通用的,未知的int
。我们正在谈论0
,它可以被转换(即使在编译时,这是我怀疑编译器正在做的事情)到UInt
。
我建议您使用int
参数(或编译器无法通过数据流分析推断的其他值),看看会发生什么。