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$ Apr 10, 2012 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$ Apr 11, 2012 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$ May 7, 2012 at 1:14

3 Answers 3


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$ Apr 15, 2012 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$ May 7, 2012 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$ May 4, 2012 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$ May 4, 2012 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, 2012 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$ May 4, 2012 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, 2012 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, 2012 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$ Apr 10, 2012 at 9:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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