我已经读过C#允许将局部常量初始化为空引用,例如:
const string MyString = null;
这样做有什么意义吗?这会有什么用处?
答案 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运算符,所以引用类型的常量唯一可能的值除了字符串之外是空的。