更新:这似乎是一个编译器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) {}
导致编译器以不同方式处理这些问题的幕后情况是什么?
答案 0 :(得分:7)
C#规范(10.6.1)中描述的那些:
带有默认参数的固定参数被称为 可选 参数 ,而没有默认参数的固定参数是 必需参数 。在a之后可能不会出现所需的参数 formal-parameter-list 中的可选参数。
ref
或out
参数不能包含默认参数。 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