Why does .NET create new substrings instead of pointing into existing strings?

后端 未结 5 1275
别跟我提以往
别跟我提以往 2021-01-02 11:35

From a brief look using Reflector, it looks like String.Substring() allocates memory for each substring. Am I correct that this is the case? I thought that woul

相关标签:
5条回答
  • 2021-01-02 12:10

    Adding to the point that Strings are immutable, you should be that the following snippet will generate multiple String instances in memory.

    String s1 = "Hello", s2 = ", ", s3 = "World!";
    String res = s1 + s2 + s3;
    

    s1+s2 => new string instance (temp1)

    temp1 + s3 => new string instance (temp2)

    res is a reference to temp2.

    0 讨论(0)
  • 2021-01-02 12:13

    Each string has to have it's own string data, with the way that the String class is implemented.

    You can make your own SubString structure that uses part of a string:

    public struct SubString {
    
       private string _str;
       private int _offset, _len;
    
       public SubString(string str, int offset, int len) {
          _str = str;
          _offset = offset;
          _len = len;
       }
    
       public int Length { get { return _len; } }
    
       public char this[int index] {
          get {
             if (index < 0 || index > len) throw new IndexOutOfRangeException();
             return _str[_offset + index];
          }
       }
    
       public void WriteToStringBuilder(StringBuilder s) {
          s.Write(_str, _offset, _len);
       }
    
       public override string ToString() {
          return _str.Substring(_offset, _len);
       }
    
    }
    

    You can flesh it out with other methods like comparison that is also possible to do without extracting the string.

    0 讨论(0)
  • 2021-01-02 12:18

    Because strings are immutable in .NET, every string operation that results in a new string object will allocate a new block of memory for the string contents.

    In theory, it could be possible to reuse the memory when extracting a substring, but that would make garbage collection very complicated: what if the original string is garbage-collected? What would happen to the substring that shares a piece of it?

    Of course, nothing prevents the .NET BCL team to change this behavior in future versions of .NET. It wouldn't have any impact on existing code.

    0 讨论(0)
  • 2021-01-02 12:26

    Not possible without poking around inside .net using String classes. You would have to pass around references to an array which was mutable and make sure no one screwed up.

    .Net will create a new string every time you ask it to. Only exception to this is interned strings which are created by the compiler (and can be done by you) which are placed into memory once and then pointers are established to the string for memory and performance reasons.

    0 讨论(0)
  • 2021-01-02 12:29

    One reason why most languages with immutable strings create new substrings rather than refer into existing strings is because this will interfere with garbage collecting those strings later.

    What happens if a string is used for its substring, but then the larger string becomes unreachable (except through the substring). The larger string will be uncollectable, because that would invalidate the substring. What seemed like a good way to save memory in the short term becomes a memory leak in the long term.

    0 讨论(0)
提交回复
热议问题