The reason for null + null == String.Empty will be because the + operator is defined on string and takes two string references. It would seem that concatenation of two null strings has been defined as an empty string.
It's an interesting observation. I guess somewhere it's probably defined that the string operators will always be called in this case. I tried to create a class that also defined a + overload but the string overload was always called..
There're tonnes of little things like this in framework. Try casting null to a SqlBinary for example, then try casting null to SqlBoolean.. they're both nullable types..