In C#, why is String a reference type that behaves like a value type?

后端 未结 12 2358
抹茶落季
抹茶落季 2020-11-22 02:04

A String is a reference type even though it has most of the characteristics of a value type such as being immutable and having == overloaded to compare the text rather than

12条回答
  •  误落风尘
    2020-11-22 02:45

    This is a late answer to an old question, but all other answers are missing the point, which is that .NET did not have generics until .NET 2.0 in 2005.

    String is a reference type instead of a value type because it was of crucial importance for Microsoft to ensure that strings could be stored in the most efficient way in non-generic collections, such as System.Collections.ArrayList.

    Storing a value-type in a non-generic collection requires a special conversion to the type object which is called boxing. When the CLR boxes a value type, it wraps the value inside a System.Object and stores it on the managed heap.

    Reading the value from the collection requires the inverse operation which is called unboxing.

    Both boxing and unboxing have non-negligible cost: boxing requires an additional allocation, unboxing requires type checking.

    Some answers claim incorrectly that string could never have been implemented as a value type because its size is variable. Actually it is easy to implement string as a fixed-length data structure using a Small String Optimization strategy: strings would be stored in memory directly as a sequence of Unicode characters except for large strings that would be stored as a pointer to an external buffer. Both representations can be designed to have the same fixed length, i.e. the size of a pointer.

    If generics had existed from day one I guess having string as a value type would probably have been a better solution, with simpler semantics, better memory usage and better cache locality. A List containing only small strings could have been a single contiguous block of memory.

提交回复
热议问题