在我可以安全地应用ToUpper(), StartWith()等方法之前,测试我所有的字符串为空是非常烦人的…

如果字符串的默认值是空字符串,我就不必测试,而且我觉得它与其他值类型(例如int或double)更一致。 此外,Nullable<String>也有意义。

那么为什么c#的设计者选择使用null作为字符串的默认值呢?

注意:这与这个问题有关,但更关注的是为什么,而不是如何处理它。


当前回答

可空类型直到2.0才出现。

如果可空类型已经在语言的开始,那么字符串将是非空的和string?是可空的。但是他们不能做到向后兼容。

很多人谈论ref-type或不是ref type,但string是一个不寻常的类,并且已经找到了解决方案,使其成为可能。

其他回答

最根本的原因/问题是CLS规范(定义了语言如何与。net交互)的设计者没有定义一种方法,通过这种方法,类成员可以指定它们必须直接被调用,而不是通过callvirt,而调用方不执行空引用检查;它也没有提供一种定义不受“正常”装箱约束的结构的方法。

Had the CLS specification defined such a means, then it would be possible for .net to consistently follow the lead established by the Common Object Model (COM), under which a null string reference was considered semantically equivalent to an empty string, and for other user-defined immutable class types which are supposed to have value semantics to likewise define default values. Essentially, what would happen would be for each member of String, e.g. Length to be written as something like [InvokableOnNull()] int String Length { get { if (this==null) return 0; else return _Length;} }. This approach would have offered very nice semantics for things which should behave like values, but because of implementation issues need to be stored on the heap. The biggest difficulty with this approach is that the semantics of conversion between such types and Object could get a little murky.

An alternative approach would have been to allow the definition of special structure types which did not inherit from Object but instead had custom boxing and unboxing operations (which would convert to/from some other class type). Under such an approach, there would be a class type NullableString which behaves as string does now, and a custom-boxed struct type String, which would hold a single private field Value of type String. Attempting to convert a String to NullableString or Object would return Value if non-null, or String.Empty if null. Attempting to cast to String, a non-null reference to a NullableString instance would store the reference in Value (perhaps storing null if the length was zero); casting any other reference would throw an exception.

Even though strings have to be stored on the heap, there is conceptually no reason why they shouldn't behave like value types that have a non-null default value. Having them be stored as a "normal" structure which held a reference would have been efficient for code that used them as type "string", but would have added an extra layer of indirection and inefficiency when casting to "object". While I don't foresee .net adding either of the above features at this late date, perhaps designers of future frameworks might consider including them.

string关键字可能使您感到困惑,因为它看起来与任何其他值类型声明完全相同,但它实际上是System的别名。在这个问题中解释的字符串。 此外,Visual Studio中的深蓝色和小写首字母可能会让人误以为它是结构体。

因为字符串是一个引用类型,引用类型的默认值是null。

可空类型直到2.0才出现。

如果可空类型已经在语言的开始,那么字符串将是非空的和string?是可空的。但是他们不能做到向后兼容。

很多人谈论ref-type或不是ref type,但string是一个不寻常的类,并且已经找到了解决方案,使其成为可能。

空字符串和空字符串是完全不同的。null是指没有值,空字符串是指空值。

编程语言对变量的“值”(在这种情况下是空字符串)进行假设,与使用任何其他不会导致空引用问题的值初始化字符串一样好。

同样,如果您将该字符串变量的句柄传递给应用程序的其他部分,那么该代码将无法验证您是故意传递了一个空白值,还是忘记填充该变量的值。

Another occasion where this would be a problem is when the string is a return value from some function. Since string is a reference type and can technically have a value as null and empty both, therefore the function can also technically return a null or empty (there is nothing to stop it from doing so). Now, since there are 2 notions of the "absence of a value", i.e an empty string and a null, all the code that consumes this function will have to do 2 checks. One for empty and the other for null.

简而言之,一个状态只有一种表示总是好的。有关empty和nulls的更广泛讨论,请参阅下面的链接。

https://softwareengineering.stackexchange.com/questions/32578/sql-empty-string-vs-null-value

在处理用户输入时,NULL vs Empty