是什么意思"结果不被认为是恒定的"

时间:2017-01-11 12:43:22

标签: c# null-coalescing-operator

MSDN中,我找到了这句话:

  

结果?即使两个参数都是常量,运算符也不被认为是常量。

这意味着什么?它们是否意味着编译器优化器不知道该值是否恒定?我没有看到另一种可能相关的方式。

编辑:为什么这不被认为是不变的?它有合理的原因吗?

编辑:这段代码给出了x的编译器错误,但不是y,为什么?:可以得到一个常量值,但是??不能? / p>

const string NULL = null;
const string val = "value";
const string x = NULL ?? val;
const string y = NULL == null ? val : NULL;

3 个答案:

答案 0 :(得分:4)

这意味着您不能在常量中使用null-coalescing运算符:

time.time()

这主要与大多数其他运算符形成对比,其中常量的操作数产生的结果也是常数:

public const int MyInt = 42; // Fine
public const int MyOtherInt = new int?(42) ?? 8; // Compiler error

这不是“优化”的问题 - 事实上,public const int SomeResult = 12 + 42; // Fine public const int OtherResult = SomeResult * 2; // Fine 运算符在大多数情况下都经过优化:

??

答案 1 :(得分:1)

如果您编写可能导致此错误消息的代码,答案将会很明显。

canActivate(): Observable<boolean> {
  onAuthStateChanged$
    .do(user => {if (!user) { this.router.navigate(['/login']); } })
    .map(user => !!user)
    .do(user => console.log('Authenticated?', user))
}

这会产生以下错误:

  

错误9表达式分配给&#39; x&#39;必须是不变的

因此编译器不会在编译时计算public void Test() { const int x = ((int?)null ?? 3); } 的结果。

相比之下,许多其他运算符(如??)是在编译时计算的,因此以下内容不会生成错误:

? :

答案 2 :(得分:1)

让我们考虑使用??运算符在常量表达式中原则上可能吗?当然,因为我们在编译时都需要所有信息。它是用C#实现的吗?不。为什么?因为C#编译器团队选择不实现此功能。以下是关于选择应实施的功能的Eric Lippert says

  

功能必须如此引人注目,以至于它们值得设计,实施,测试,记录和发布功能的巨大成本。它们必须值得使语言复杂化并使将来设计其他功能变得更加困难。

什么时候可以用?运算符在常量表达式?当 expr-first 是空文字时。而常量类型是对象或字符串(记住,C#团队已经决定不添加Nullables对常量的支持)。这个功能将添加到该语言?

const string s = null ?? "foo";

这不会为语言增添任何便利。它与

完全相同
const string s = "foo";

但更复杂。