为什么有人会这样做:
const object useless = null;
const IEnumerable meaningless = null;
Eric Lippert 说功能在默认情况下是未实现的,每一种可能性都会增加测试、维护等方面的工作量……为什么需要将引用类型的空值作为常量?
为什么有人会这样做:
const object useless = null;
const IEnumerable meaningless = null;
Eric Lippert 说功能在默认情况下是未实现的,每一种可能性都会增加测试、维护等方面的工作量……为什么需要将引用类型的空值作为常量?
Eric Lippert 说功能在默认情况下是未实现的,每一种可能性都会增加测试、维护等方面的工作量……为什么需要将引用类型的空值作为常量?
实现“任何实例字段都可以标记为const
”的功能比实现“如果存在该类型的任何非空编译时文字,任何实例字段都可以标记为 const”的功能更容易。
您实质上是在提议添加一个功能,即“不能将字段标记为const
好像没有该类型的非空编译时文字。” 该功能默认情况下未实现,如果添加,将增加测试、维护等方面的工作量。
Servy的观点很好。让我以稍微不同的方式解释这一点。
让我们从问一个更一般的问题开始:“C# 1.0 编译器是否应该将引用类型的 null 文字分类为常量?” 我想强调的是,我们在这里推理的是 C# 1.0,因此您不会考虑任何关于可空值类型或泛型的问题。
那么,将任何事物归类为常数有什么意义呢?关键是某些语言结构需要常量:
case
条款的价值常量对可达性分析有影响:
if (0 == 0)
M(out x); // always reached, so x is initialized
else
M(out y); // unreachable, so y is not initialized.
现在,让我们假设我们接受它null
在属性中是有用的case null
,虽然它有点奇怪,
if (null == null)
应该被视为常数真。那么您的建议是说null
这三种方式都是常数,但不能分配给const
本地或字段???这是一个奇怪的限制;如果null
在需要常量的所有其他情况下都可以将其视为常量,那么为什么在定义字段或本地时不应将其视为常量?
但当然我还没有回答你的实际问题,即“这什么时候有用?”
好吧,再一次,让我们推回去。什么时候常数有用?编译器将常量视为它们的值被替换为它们的用法,所以你为什么要说:
const int Blah = 0;
...
if (x == Blah)
当你可以简单地说
if (x == 0)
? 当我这样说时,我希望推理是显而易见的。使用任何常量字段或局部变量的原因是为一个值命名,以便代码的读者更好地理解它。空常量字段或本地完全相同。可以说阅读起来更清楚:
if (node != Empty)
stack.Push(node.Right);
比
if (node != null)
stack.Push(node.Right);
在大多数情况下,我会说不。
我能看到类似有用的东西的唯一情况是在预处理器条件内。例如:
#if DEBUG
const Object obj = "Debug text";
#else
const Object obj = null;
#endif
它对于null
具有特殊含义的(通常是递归的)数据结构有意义,除了(或除了)通常。
例如,实现的集合 wherenull
表示空集合。将集合实现为二叉搜索树的链表将使这成为一件很自然的事情。在这种情况下,定义const Set Empty = null
将是有意义的。经常与滥用运算符重载以及大量静态方法一起出现。
这种做法符合理论计算机科学中经常使用的惯例,它可以被视为理论泄漏到实践中。
这是否是一件好事(tm)是另一回事,但它确实发生了。
有一个非常常见的哨兵值模式,其中一些“特殊”实体用作“终止循环”操作。我可以将以下代码视为此类代码的合理常量(请注意,显然样本非常做作,有真正的算法依赖于哨兵):
const Item ItemLookpupSentinel = null;
Item Serach(IEnumerable<Item> items)
{
var sequenceWithSentinel =
items.Concat(Enumerable.Repeat(ItemLookpupSentinel, 1));
foreach(var item in sequenceWithSentinel )
{
if (item == ItemLookpupSentinel)
return null;
}
}
一个有用的引用类型常量的例子是:
const string UsefulSite = "http://stackoverflow.com";
仅仅因为分配给常量不是很有用,就禁止引用类型常量null
,似乎不太合适。值类型常量也可能毫无用处:
const int FourtyTwo = 42;
充分利用 C# 为您提供的可能性取决于您。
希望能够将 null 视为 const 的一个原因是,您可以提供一个默认为 null 的可选参数(用于引用类型)。这不是一个合理的特性(默认参数在 C# 1.0 中不存在),但它有利于现在允许将引用类型声明为 const(为了保持一致性)。