The quick answer is: the type
System.String
is the class, that is, a reference type closely simulating value type semantics.
Comparison of reference type by value (your second question) is not a miracle.
You can easily implement such thing in your own class. This is done by implementing of the custom operators "==" and "!=". For referential equality, you should use the static (and of course, non-virtual, not to be overridden) method
System.Object.ReferenceEquals
. You need to use this method when overriding equality. The algorithm is this: 1) check up if one or both operands for null and return false and true for equal (use the method mentioned above); 2) if not are non-null, perform semantic test (in case of string, by content).
But, in case of
System.String
, it's much more complex and interesting! The referentially different strings of the same content can reference the exact same physical memory, and assignment of the value to the string generally changes its referential identity; this is done to reuse memory used by different string in a way transparent to the user. This is called "
string interning".
Please see:
http://en.wikipedia.org/wiki/String_interning[
^];
see this method in MSDN and code samples explaining string behavior:
http://msdn.microsoft.com/en-us/library/system.string.intern.aspx[
^].
As to your third question: still, string is a reference type. I explained it above.
Interesting, isn't it?
—SA