局部常量初始化为null引用

时间:2011-05-10 22:06:11

标签: c# string reference null const

我已经读过C#允许将局部常量初始化为空引用,例如:

const string MyString = null;

这样做有什么意义吗?这会有什么用处?

6 个答案:

答案 0 :(得分:5)

我的猜测是因为null 一个有效值,可以分配给引用类型和可空值类型。 我看不出有任何理由禁止这样做。

可能会有一些非常有用的案例,例如多重定位条件编译。 IE您希望为一个平台定义一个常量,但由于缺少功能而将其定义为另一个平台的空值。

Ex,可能有用的用法:

#IF (SILVELIGHT)
    public const string DefaultName = null;
#ELSE
    public const string DefaultName = "Win7";
#ENDIF 

答案 1 :(得分:2)

实际上,您可以将本地const字符串和readonly引用类型初始化为null,即使它似乎是多余的,因为它们的默认值仍为null。< / p>

然而,事实仍然是null是一个足以初始化字符串和引用类型的编译时常量。因此,编译器必须一路走才能考虑,识别和拒绝这种特殊情况,即使它从语言角度来看仍然完全有效。

这样做的好处是有争议的,首先可能不值得努力。

答案 2 :(得分:2)

如果你想编写没有关键字的代码,可以使用它,如果你想要的话:

const string UninitializedSetting = null;

if (mySetting == UninitializedSetting)
{
    Error("mySetting string not initialized");
}

答案 3 :(得分:1)

选择命名一个值(而不是使用就地魔术常数),使用const,设置为null或多或少是正交问题,尽管我同意维恩图可能这三个人的重叠区域非常小:)

我能想到的一个案例是,当您拥有与代码相比更多或更多的丢弃数据时,但您希望确保在编写或维护代码时不会意外地更改这些值。这种情况在单元测试中相当普遍:

[Test]
public void CtorNullUserName()
{
    const string expectedUserName = null;

    var user = new User(expectedUserName);

    Assert.AreEqual(expectedUserName, user.Name, "Expected user name to be unchanged from ctor");
}

你可以用多种方式构建这样的代码,而不涉及将null分配给const,但这仍然是一个有效的选择。

这可能有助于解决方法重载问题:

public class Something
{
    public void DoSomething(int? value) { Console.WriteLine("int?"); }
    public void DoSomething(string value) { Console.WriteLine("string"); }
}

// ...

new Something().DoSomething(null); // This is ambiguous, and won't compile

const string value = null;
new Something().DoSomething(value); // Not ambiguous

答案 4 :(得分:0)

如果您使用常量,例如,为了配置您的应用程序,为什么不呢? null值可以表示有效状态 - 例如没有安装记录器。另请注意,当您声明局部常量时,可以将其初始化为全局常量给出的值(这可能是一个更有趣的场景)。

编辑:另一个问题是,无论如何使用const有什么好处?对于配置,您可能希望配置文件和其他变量通常更改(除非它们是不可变的,但readonly更适合...)

答案 5 :(得分:0)

除了已经指出的情况之外,它可能与C#语言的怪癖有关。 C#规范3.0第8.5.2节规定:

  

本地常量声明的类型和常量表达式必须遵循与常量成员声明(第10.4节)相同的规则。

在10.4内读取如下:

  

如第7.18节所述,constant-expression是一个可以在编译时完全评估的表达式。由于创建除字符串以外的引用类型的非空值的唯一方法是应用new运算符,并且因为常量表达式中不允许使用new运算符,所以引用类型的常量唯一可能的值除了字符串之外是空的。