带有文字数字的条件运算符返回类型

时间:2013-08-28 20:19:15

标签: c# implicit-conversion conditional-operator return-type

?: Operator (C# Reference)

  

first_expression和second_expression的类型必须是   相同,或者必须存在从一种类型到另一种类型的隐式转换。

Integer literals

  

如果文字没有后缀,则它具有第一种类型   它的值可以表示为:int,uint,long,ulong。

考虑:

var value = test ? (Int64)1 : 0;

0,没有后缀的十进制数字文字将转换为intint可以隐式转换为Int64。由于此转换仅在一个方向上发生,因此我们可以确定返回值将是Int64。

然而:

var value = test ? (UInt64)1 : 0;

UInt64int无法隐式转换为彼此,但此代码会编译并运行,结果类型为UInt64

0的类型在什么时候确定?

如果两种类型可以隐式地相互转换,那么你最终会选择哪两种类型? (我认为这不会发生,但是用户生成的类可以实现这样的转换。)

之前的研究:
我发现了其他几个类似标题的问题,但它们都与null或可空类型相关。

相关性: 这在我的代码中很重要,因为我们立即将此结果传递给ByteWriter.Write,并希望以正确的重载结束写入正确的字节数。这些例子当然大大简化了。

替代语法使结果显式可能是最清楚的选择,无论实际发生什么没有显式转换:

var value = test ? (UInt64)1 : (UInt64)0;

2 个答案:

答案 0 :(得分:3)

请注意,当数字为编译时常量(文字)时,整数类型之间存在一组隐式转换,而当它们不是常量时,则存在另一组转换。

你有趣的例子是:

var value = test ? (UInt64)1 : 0;

也可以写成:

var value = test ? 1ul : 0;

其中ul后缀表示ulong,即System.UInt64

当使用文字(常量)时,确实存在从intSystem.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!

我们看到,对于非常量,不存在任何方向的隐式转换,因此ab没有最佳公共类型,但这会失败。

答案 1 :(得分:1)

没错,泛型 int不能隐式转换为UInt任何长度。但在这里,我们不是在谈论一个通用的,未知的int。我们正在谈论0,它可以被转换(即使在编译时,这是我怀疑编译器正在做的事情)到UInt

我建议您使用int参数(或编译器无法通过数据流分析推断的其他值),看看会发生什么。