I've been trying to understand the rationale behind the design of the C# language. Are there any specific advantages that can be gleaned from allowing string type variables to contain null?

  • 4
    $\begingroup$ It's a billion dollar mistake that stuck. $\endgroup$ – Gilles 'SO- stop being evil' Apr 10 '12 at 20:25
  • 2
    $\begingroup$ Familiarity. The other choice would have forced programmers to deal with issues that (in C and Java) they are not forced to deal with. Too much unfamiliarity might have killed C# as a competitor for Java. In other words, it was a `marketing' decision, not a technical one. $\endgroup$ – Jacques Carette Apr 11 '12 at 1:11
  • $\begingroup$ Many people agree that implicitly nullable types are evil, and I understand that opinion. But I find it hard to turn such arguments into more than a personal taste and a poll. For example, in many languages, functions are allowed to have side effects. Pure functional programmers may say, “Implicit side effects are evil. Side effects should be made explicit in types.” I do not necessarily agree with this, although I still think that implicitly nullable types are evil. I am not sure what the difference is. $\endgroup$ – Tsuyoshi Ito May 7 '12 at 1:14

At the risk of starting a religious war, I will express my opinion that there are no advantages to having nullable types. These should always be replaced by a sum type such as Ocaml option or Haskell Maybe (paired with sane deconcstructors for such types that force the programmer to always consider both possibilities).

The main reason for this is that null pointers, null objects, and the like are responsible for many, many bugs and countless headaches.

  • $\begingroup$ I should try getting 10 upvotes for such a comment on reddit... that would be a real challenge. $\endgroup$ – Andrej Bauer Apr 15 '12 at 14:46
  • $\begingroup$ “null pointers, null objects, and the like are responsible for many, many bugs and countless headaches.” Is there any study showing this rigorously? I do not like nullable object types either, but I find it hard to back up the claims like this by facts. $\endgroup$ – Tsuyoshi Ito May 7 '12 at 1:01

Since the .NET Framework is database oriented, it would stand to reason that the designers of the Common Runtime Languate introduced nullable types to mirror SQL values. A null value has special meaning in SQL and is perfectly valid. For instance, two queries with the clause WHERE table.a <> "" and table.a <> NULL would return two separate results.

Out of convenience and brevity, the CLR introduced nullable types to make it easier to translate values back and forth from SQL without extensive coding for intrinsic types such as int, float, etc. The nullable versions are int?, float?, etc.

Strings are intrinsic types in .NET, but they are really plain old objects under the hood. Consequently, there's no need for a string? type.

  • $\begingroup$ The strings are not just plain old objects. The CLR module format uses constant pools containing strings (like Java class files) to define method and property names for classes. Thus the language has an intrinsic string type that is prior to the definition of classes including that of the base class. $\endgroup$ – Mike Samuel May 4 '12 at 15:24
  • $\begingroup$ The reason for NULL in the CLR is not interoperability with SQL, but interoperability with COM and OLE which are two object models used extensively by Windows and the foundation classes (MFC). Both of these used NULL as a possible return value for pointer types because of Window's C/VC++ heritage. NULL in CLR == NULL in VC++ == NULL in C. NULL in CLR != NULL in SQL. $\endgroup$ – Mike Samuel May 4 '12 at 15:29
  • $\begingroup$ MSDN says: "The string type represents a string of Unicode characters. string is an alias for System.String in the .NET Framework." $\endgroup$ – user148298 May 4 '12 at 15:29
  • $\begingroup$ That's probably fuzzy language, .NET strings are sequences of UTF-16 code-units, not code-points. The use of intrinsic strings and blobs in object metadata is described in the CLR docs thus: "Metadata also stores information in four heap structures: string, blob, user string, and GUID. All the strings used to name types and members are stored in the string heap. For example, a method table does not directly store the name of a particular method, but points to the method's name stored in the string heap." $\endgroup$ – Mike Samuel May 4 '12 at 15:44
  • $\begingroup$ Getting back to NULL, I was talking about intrinsic types vs POCOs. POCOs have always been nullable, but nullable intrinsic types were introduced with .NET 2.0. MSDN says that they were introduced to make it simpler to persist uninitialized variables (SQL and XML serialization). Support for COM has always been a part of the CLR since .NET 1.0. $\endgroup$ – user148298 May 4 '12 at 16:01

Strings are object variables, unlike the atomic types supported for performance reasons.

For orthoginality it is easier if they are implemented in the same way as any other object and permitted to have a null value.

In practice, strings are rather special and share storage across all instances. This provides the side effect that all string objects with the same value contain the same pointer making comparison trivial.

  • $\begingroup$ If I have three strings with the same value "Hello World!" and I change one of them it would change all three or would it create a new storage for the one I changed? If it does, then the CLR has a really impressive memory manager. $\endgroup$ – user148298 Apr 10 '12 at 2:23
  • 3
    $\begingroup$ .NET strings are immutable, so you can't change them. Whether or not three strings with the same value are the same object or not depends on the details of string interning, which are set by the programmer at program startup. $\endgroup$ – Neel Krishnaswami Apr 10 '12 at 9:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.