从编译器的角度来看,字符串是什么样的?

hom*_*omk 11 .net c# memory compiler-construction string

C,编译器有一个指向字符串开头的指针,并有一个结束符号('\0').如果用户想要计算字符串的长度,则编译器必须计算字符串数组的元素,直到找到它为止'\0'.

UCSD-strings,编译器具有第一个符号中字符串的长度.

编译器会考虑什么C#-strings?是的,从用户的角度Stringobject,有一个领域Length,我不是在谈论高层次的东西.我想知道深度算法; 例如,编译器如何计算字符串的长度?

Tam*_*red 21

我们执行以下代码:

string s = "123";
string s2 = "234";
string s3 = s + s2;
string s4 = s2 + s3;
Console.WriteLine(s + s2);
Run Code Online (Sandbox Code Playgroud)

现在让我们在最后一行放置一个断点并打开内存窗口:

字符串

s3在内存窗口中写入,我们可以看到一个接一个地分配的2(s3s4)字符串,开头有4个字节的大小.

您还可以看到已分配其他内存,例如strings类类型标记和其他string类数据.

string本身包含一个成员private int m_stringLength;包含的长度string,这也使得string.Concat()执行超快速(通过分配在一开始的整个长度):

int totalLength = str0.Length + str1.Length + str2.Length;

String result = FastAllocateString(totalLength);
FillStringChecked(result, 0, str0);
FillStringChecked(result, str0.Length, str1);
FillStringChecked(result, str0.Length + str1.Length, str2);
Run Code Online (Sandbox Code Playgroud)

我觉得有一点奇怪的是,实施IEnumerable<char>.Count()string使用默认的实现,这意味着迭代项目一个一个地做不同ICollection<T>就像List<T>IEnumerable<char>.Count()是利用其实现的ICollection<T>.Count属性.

  • @homk如果那是你想知道的,那么你真正的问题与"从编译器的角度来看"无关. (2认同)

Jak*_*rtz 6

在C#中,字符串的长度存储在私有字段([NonSerialized]private int m_stringLength;)中的对象中,不必在运行时计算.

String类的源代码可在线获取.