为什么有人会这样做:
const object useless = null;
const IEnumerable meaningless = null;
Eric Lippert说默认情况下功能未实现,每种可能性都会增加测试,维护等方面的工作量......为什么参考类型的空值需要作为常量?
答案 0 :(得分:4)
Eric Lippert说默认情况下功能未实现,每种可能性都会增加测试,维护等方面的工作量......为什么参考类型的空值需要作为常量?
实现“任何实例字段可以标记为const
”的功能比实现以下功能更容易:“如果存在任何非空编译,则任何实例字段都可以标记为const该类型的时间文字“。
您基本上建议添加一项功能,该功能说:“如果该类型没有非空的编译时文字,则无法将字段标记为const
。”默认情况下,该功能未实现,如果添加,将在测试,维护等方面增加更多工作量。
答案 1 :(得分:4)
Servy的观点很好。让我以稍微不同的方式解释这一点。
让我们首先提出更一般的问题“C#1.0编译器应该将引用类型的空文本分类为常量吗?”我想强调一下,我们在这里推理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);
答案 2 :(得分:1)
在大多数情况下,我会说不 唯一可以看到类似内容的情况是在预处理器条件下。例如:
#if DEBUG
const Object obj = "Debug text";
#else
const Object obj = null;
#endif
答案 3 :(得分:1)
null
具有特殊含义的(通常是递归的)数据结构是有意义的,而不是通常的(或除此之外)。
例如,实现了null
表示空集的集合。将集合实现为二叉搜索树的链接列表将使这成为自然而然的事情。在这种情况下,定义const Set Empty = null
会有所帮助。通常与滥用运算符重载以及大量静态方法一起看。
这种做法符合理论计算机科学中常用的惯例,可以看作理论渗入实践。
这是否是一件好事(tm)是另一回事,但确实发生了。
答案 4 :(得分:1)
有一种非常常见的sentinel value模式,其中一些“特殊”实体用作“终止循环”操作。我可以看到以下是这种代码的合理常量(注意,显然样本非常人为,有真正的算法依赖于哨兵):
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;
}
}
答案 5 :(得分:1)
有用的参考类型常量的一个例子是:
const string UsefulSite = "http://stackoverflow.com";
禁止引用类型常量只是因为将null
赋值给常量不是很有用,似乎不太合适。值类型常量也很无用:
const int FourtyTwo = 42;
由您来充分利用C#为您提供的各种可能性。
答案 6 :(得分:0)
From comments, as @Brian points out:
希望能够将null视为const的一个原因是,您可以提供一个可选参数(对于引用类型),默认为null。这不是一个合理的特性(C#1.0中不存在默认参数),但它支持允许引用类型现在声明为const(为了一致性)。