简体   繁体   English

System.String 底层实现

[英]System.String underlying implementation

I was recently trying to do the following in c#我最近尝试在 c# 中执行以下操作

string str = "u r awesome";
str[0]="i";

And it wouldn't work because apparently str[i] is only a get not a set, so I was wondering what the underlying implementation of string is that would force str[i] to only be a get.它不起作用,因为显然 str[i] 只是一个 get 而不是一个集合,所以我想知道 string 的底层实现是什么会强制 str[i] 只是一个 get。

Isn't it just a managed wrapper for a char *?它不只是一个 char * 的托管包装器吗? So then why can't I set str[i]?那么为什么我不能设置 str[i] 呢?

You can't set characters of a string because the .NET String class is immutable -- that means that its contents cannot be changed after it is created.您不能设置字符串的字符,因为 .NET String类是不可变的——这意味着它的内容在创建后无法更改。 This allows the same string instance to be used many times safely, without one object worrying that another object is going to stomp on its strings.这允许安全地多次使用相同的字符串实例,而无需一个对象担心另一个对象会踩到它的字符串。

If you need a mutable class that lets you manipulate a string of characters, consider using StringBuilder instead.如果您需要一个允许您操作字符串的可变类,请考虑改用StringBuilder

If you want to compare to C, the String type is like const char * except that you cannot just cast away the constness.如果您想与 C 进行比较, String类型就像const char *一样,只是您不能抛弃const char * StringBuilder is more like a char * (with automatic allocation resizing) and with a method ( ToString() ) to create a new, independent String instance from its contents. StringBuilder更像是一个char * (具有自动分配调整大小)和一个方法( ToString() )从其内容创建一个新的、独立的String实例。

The answers the others gave concerning immutability are of course correct and are the "actual" cause of the issue your having.其他人给出的关于不变性的答案当然是正确的,并且是您遇到问题的“实际”原因。

Since you specifically asked about the underlying implementation (and if just out of curiosity), and as a reference to others that might stumble upon this question, here is some more information about that topic from Eric Lippert :由于您特别询问了底层实现(如果只是出于好奇),并且作为对可能偶然发现此问题的其他人的参考,这里是Eric Lippert提供的有关该主题的更多信息:

"In the .NET CLR, strings are laid out in memory pretty much the same way that BSTRs were implemented in OLE Automation: as a word-aligned memory buffer consisting of a four-byte integer giving the length of the string, followed by the characters of the string in two-byte chunks of UTF-16 data, followed by two zero bytes." “在 .NET CLR 中,字符串在内存中的布局与在 OLE 自动化中实现 BSTR 的方式几乎相同:作为字对齐的内存缓冲区,由给出字符串长度的四字节整数组成,后跟UTF-16 数据的两字节块中的字符串字符,后跟两个零字节。”

Note the "pretty much" part here, however BSTR themselves are also explained in Eric's blog .注意这里的“相当多”部分,但是 BSTR 本身也在Eric 的博客中进行了解释。

Mind you, that all of this should be considered an implementation detail.请注意,所有这些都应该被视为一个实现细节。 And even though it shouldn't really concern most of us, it might help though during debugging interop issues or in general understanding.即使它不应该真正关心我们大多数人,但在调试互操作问题或一般理解期间它可能会有所帮助。

Like answered by cdhowie, it is not the same to the concept of string in c/c++就像cdhowie回答的一样,和c/c++中字符串的概念不一样

If you want to the the above, as a suggestion you can try to mimic the implementation through container such as below如果您想要上述内容,作为建议,您可以尝试通过容器模拟实现,如下所示

List<char> str = new List<char>("u r awesome");
str[0] = 'i';
str[2] = 'm';
Console.WriteLine(str.ToArray());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM