编译时常量差异

时间:2013-09-11 12:05:22

标签: c#

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

const int MyInt = default(int);

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

对我来说混淆的主要原因是没有意识到default(DateTime)是在可选参数中专门处理的(我得出的错误结论是default(DateTime)被视为编译时常量到期忽略其他可能条件的错误消息)。 MarcinJuraszek在回答中解决了这个问题。

<小时/> 原始问题:

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

为什么以下内容有效:

// 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) {}

导致编译器以不同方式处理这些问题的幕后情况是什么?

3 个答案:

答案 0 :(得分:7)

C#规范(10.6.1)中描述的那些:

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

     

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

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

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

答案 1 :(得分:4)

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

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

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

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

关于const定义;

  

常量表达式是一个可以在中完全计算的表达式   编译时间。

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

答案 2 :(得分:4)

因为只有值const的{​​{1}}可能会毫无用处: - )......之后你甚至无法改变它: - )

请注意,default(TypeOfCost) 是一个常量表达式

来自C#规范(5.0):default(TypeOfConst) ... 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