将引用类型声明为const是否有用?

时间:2013-12-13 19:42:17

标签: c# const constants design-decisions

为什么有人会这样做:

const object useless = null;
const IEnumerable meaningless = null;

Eric Lippert说默认情况下功能未实现,每种可能性都会增加测试,维护等方面的工作量......为什么参考类型的空值需要作为常量?

7 个答案:

答案 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(为了一致性)。