【问题标题】:Compile-time constant discrepency编译时常数差异
【发布时间】:2013-09-11 12:05:22
【问题描述】:

更新:这似乎是一个编译器红鲱鱼,因为以下内容实际上是有效的:

const int MyInt = default(int);

问题在于DateTime 不是有效的const,而不是default 的使用。

让我感到困惑的主要原因是没有意识到 default(DateTime) 是在可选参数中专门处理的(我得出了一个错误的结论,即由于错误消息,default(DateTime) 被视为编译时常量省略其他可能的条件)。 MarcinJuraszek 在他的回答中解决了这个问题。


原问题:

这是从 this answer 的 Marc Gravell 的评论中无耻地抄袭到另一个问题。

为什么以下有效:

// No compiler errors, default(DateTime) seems to satisfy the compile-time constant requirement.
public static void DoSomething(DateTime date = default(DateTime))
{ 
}

但以下不是:

// Compiler error: "Constant initializer must be compile-time constant.
const DateTime MyDate = default(DateTime); 

由于两者似乎都需要“编译时常量”(显然,如果您尝试为可选参数提供类似 DateTime.MinValue 的内容,编译器会抱怨它不是编译时常量):

// Compiler error: Default parameter value for 'date' must be a compile-time constant.
public static void DoSomething(DateTime date = DateTime.MinValue) {}

导致编译器以不同方式处理这些的幕后发生了什么?

【问题讨论】:

  • 可选参数是事后添加的。
  • 查看编译器消息。可能会告诉你一些事情。
  • @DanielA.White - default, IIRC 也是如此。它仅在泛型存在时添加。
  • @usr 好吧,编译器消息是混淆伙伴的来源。
  • 它似乎是规范的一部分。我真的应该在某个时候更彻底地阅读!

标签: c#


【解决方案1】:

这在 C# 规范 (10.6.1) 中有描述:

带有默认参数固定参数被称为可选参数 参数,而没有默认参数固定参数必填参数。必需的参数可能不会出现在 formal-parameter-list中的可选参数。

refoutparameter 不能有 默认参数default-argument 中的 表达式 必须是以下之一:

  • 常量表达式
  • new S() 形式的表达式,其中 S 是值类型
  • default(S) 形式的表达式,其中 S 是值类型

但你是对的,要求编译时常量的错误信息不好。

【讨论】:

  • 你也应该说默认是运行时评估的算子,那么这个答案就完美了
  • @Marcin 7.19 的 C# 规范 (5.0): 7.19 Constant expressions... A constant-expression is an expression that can be fully evaluated at compile-time.... Only the following constructs are permitted in constant expressions:... • Default value expressions
【解决方案2】:

因为只能具有 default(TypeOfCost) 值的 const 可能毫无用处 :-)...而且您以后甚至无法更改它 :-)

注意default(TypeOfConst) 一个常量表达式

来自 C# 规范 (5.0):7.19 Constant expressions... A constant-expression is an expression that can be fully evaluated at compile-time.... Only the following constructs are permitted in constant expressions:... • **Default value expressions**

错误是const DateTime是非法的..

10.4 Constants...The type specified in a constant declaration must be sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, an enum-type, or a reference-type.

【讨论】:

  • 同意,但default(DateTime) 的定义在一种情况下是“编译时常量”而不是在另一种情况下是有问题的,而不是它的用途;-)
  • PI 只能取 3.14 的值……但我觉得还是有用的。
  • @AdamHouldsworth 我得到的错误是The type 'System.DateTime' cannot be declared const
  • @xanatos 啊,那里有两个错误,构建报告两个但IDE只报告一个。
  • @AdamHouldsworth 您可以添加一个更有趣的示例,即您不能使用default(DateTime) 作为属性参数:-)
【解决方案3】:

default() 在运行时进行评估。 DateTime.MinValue 未声明为 const。

只有声明为 const 的符号才能用于成员初始化和属性声明。

可选参数是一种特殊情况。编译器为您生成重载。语义上它需要一个 const,但从技术上讲,默认值是可以的,因为编译器知道如何在生成的重载中使用它。

MSDN 声明可选参数接受 default()new() 设计为 http://msdn.microsoft.com/en-us/library/dd264739.aspx

关于 const 定义;

常量表达式是可以在 编译时间。

我同意这种区别是微不足道的,它不止一次让我绊倒。

【讨论】:

  • 我不认为这涵盖了这个问题。我知道DateTime.MinValue 不是恒定的,但在一种情况下default(DateTime) 是,而在另一种情况下它“不是”。
  • C# 规范 (5.0) 的 7.19:7.19 Constant expressions... A constant-expression is an expression that can be fully evaluated at compile-time.... Only the following constructs are permitted in constant expressions:... • Default value expressions
猜你喜欢
  • 2013-02-24
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多