As the following code is possible in C#, I am intersted whether string is actually an array of chars:
由于在C#中可以使用以下代码,因此我认为string是否实际上是一个chars数组:
string a="TEST";
char C=a[0]; // will be T
12 个解决方案
#1
17
System.String is not a .NET array of Char because this:
System.String不是Char的.NET数组,因为这样:
char[] testArray = "test".ToCharArray();
testArray[0] = 'T';
will compile, but this:
将编译,但这:
string testString = "test";
testString[0] = 'T';
will not. Char arrays are mutable, Strings are not. Also, string is Array
returns false, while char[] is Array
returns true.
将不会。字符串数组是可变的,字符串不是。另外,string是Array返回false,而char []是Array返回true。
#2
14
No, it's not an array. But it does have an indexer. Best of both worlds.
不,这不是阵列。但它确实有一个索引器。两全其美。
#3
5
Strings in .NET are backed by the System.String
class, which internally uses a bunch of unsafe methods to do pointer manipulation on the actual string data using standard C memory manipulation techniques.
.NET中的字符串由System.String类支持,该类在内部使用一堆不安全的方法,使用标准的C内存操作技术对实际的字符串数据进行指针操作。
The String
class itself does not contain an array, but it does have an indexer property which allows you to treat the data as if it were an array.
String类本身不包含数组,但它有一个indexer属性,允许您将数据视为数组。
#4
3
No, String is a class in .Net. It may be backed by an array. but it is not an array. Classes can have indexers, and that is what String is doing.
不,String是.Net中的一个类。它可能由数组支持。但它不是一个数组。类可以有索引器,这就是String正在做的事情。
See comments for elaboration on this statement: From what I understand, all strings are stored in a common blob. Because of this, "foo" and "foo" point to the same point in that blob... one of the reasons strings are immutable in C#.
请参阅有关此声明的详细说明:根据我的理解,所有字符串都存储在一个公共blob中。因此,“foo”和“foo”指向该blob中的相同点...字符串在C#中不可变的原因之一。
#5
2
A string
is not a char[]
, although it does have a .ToCharArray()
. Also it does have an indexer, which allows you to access characters individually, like you've shown. It is likely that it was implemented with an array internally, but that's an implementation detail.
字符串不是char [],尽管它有一个.ToCharArray()。它还有一个索引器,它允许你单独访问字符,就像你已经显示的那样。它可能是在内部使用数组实现的,但这是一个实现细节。
#6
2
A string object contains a continuous block of characers, just like an array of characters, but the string object neither is, nor contains an array object.
字符串对象包含一个连续的characers块,就像字符数组一样,但字符串对象既不是,也不包含数组对象。
The compiler knows that the string string is immutable, so it can do certain optimisations when you access a string, in the same manner that it does optimisations when you access an array. So, when you access a string by index, it's likely that the code ends up accessing the string data directly rather than calling an indexer property.
编译器知道字符串字符串是不可变的,因此在访问字符串时它可以执行某些优化,其方式与访问数组时的优化方式相同。因此,当您通过索引访问字符串时,代码可能最终直接访问字符串数据而不是调用索引器属性。
#7
2
To add a little to Scott Dorman's and Gufa's answer. If you use Windbg and !DumpObject on the string 'abcd' you'll get somthing like this.
添加一点Scott Dorman和Gufa的答案。如果你在字符串'abcd'上使用Windbg和!DumpObject,你会得到这样的东西。
0:000> !do 01139b24
Name: System.String
MethodTable: 79330a00
EEClass: 790ed64c
Size: 26(0x1a) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: abcd
Fields:
MT Field Offset Type VT Attr Value Name
79332c4c 4000096 4 System.Int32 1 instance 5 m_arrayLength
79332c4c 4000097 8 System.Int32 1 instance 4 m_stringLength
793316e0 4000098 c System.Char 1 instance 61 m_firstChar
79330a00 4000099 10 System.String 0 shared static Empty
>> Domain:Value 00181b38:01131198 <<
79331630 400009a 14 System.Char[] 0 shared static WhitespaceChars
>> Domain:Value 00181b38:011318b8 <<
You'll notice its only got three instance fields. m_arrayLength, m_stringLength and m_firstChar. It does not contain an instance System.Char[] The other 2 fields are static shared so every System.String has the same Empty string and WhitespaceChar Char Array.
你会注意到它只有三个实例字段。 m_arrayLength,m_stringLength和m_firstChar。它不包含实例System.Char []其他2个字段是静态共享的,因此每个System.String都具有相同的空字符串和WhitespaceChar字符数组。
If you follow that with a DumpByte you'll see the string data (in this case abcd) that's in the heap which of course starts at offset 0x0c (m_firstChar) and is 8 bytes wide (m_stringLength 4 x 2 for unicode).
如果您使用DumpByte,您将看到堆中的字符串数据(在本例中为abcd),当然从偏移量0x0c(m_firstChar)开始,宽度为8字节(对于unicode,m_stringLength为4 x 2)。
0:000> db 01139b24 L1A
01139b24 00 0a 33 79 05 00 00 00-04 00 00 00 61 00 62 00 ..3y........a.b.
01139b34 63 00 64 00 00 00 00 00-00 00 c.d......
If you were to look in the SSCLI you'll see that it, as Scott says, either runs unsafe code and uses pointer techniques to read the data using the m_firstChar and the m_stringLength.
如果您要查看SSCLI,您会看到它,正如Scott所说,它运行不安全的代码并使用指针技术使用m_firstChar和m_stringLength读取数据。
#8
2
String is a class which takes an array of char to initialized itself, So when you try to fetch the element at some index it returns char. Check the string class
String是一个类,它接受一个char数组来自己初始化,所以当你尝试在某个索引处获取元素时,它返回char。检查字符串类
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
{
// Summary:
// Initializes a new instance of the System.String class to the value indicated
// by an array of Unicode characters.
//
// Parameters:
// value:
// An array of Unicode characters.
[SecuritySafeCritical]
public String(char[] value);
}
Also see String class declaration.
另请参见String类声明。
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
Which is inherited by IEnumerable<char>
.
哪个由IEnumerable
Inside the string class there is a get property which returns the char when index is passed, see the image. Which clearly says that Gets the System.Char object at a specified position in the current System.String
在字符串类中有一个get属性,它在传递索引时返回char,请参见图像。这清楚地说明了在当前System.String中的指定位置获取System.Char对象
public char this[int index] { get; }
#9
1
A string
is not an array of char
s until you convert it to one. The notation is simply used to access characters at different positions (indices) in a string.
在将字符串转换为字符串之前,字符串不是字符数组。该表示法仅用于访问字符串中不同位置(索引)的字符。
#10
1
Using Reflector, we can see that string does implement IEnumerable<char>
. So, it is not a character array, but in essence can be used like one.
使用Reflector,我们可以看到字符串确实实现了IEnumerable
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
EDIT:
编辑:
Implementing IEnumerable<char>
does not mean that the type will be indexed. I didn't mean to convey that. It means that you can enumerate over it and use it like a collection. A better way of wording what I meant to say is that a string isn't a character array, but is a collection of characters. Thanks for the comment.
实现IEnumerable
#11
1
Strings is simply not an array, in the sense that "Hello" is char[]
is evaluated to false
.
字符串根本不是数组,因为“Hello”是char []被评估为false。
#12
0
Everyone has given half the answer, so here is both parts:
每个人都给出了一半的答案,所以这里有两个部分:
1) Strictly speaking, yes, a String in .NET is an array of characters. It is so both in its internal implementation, and by the symantic definition of an array.
1)严格来说,是的,.NET中的String是一个字符数组。它的内部实现和数组的语义定义都是如此。
2) However String is, as others have pointed out, somewhat peculiar. It is not a System.Array as all other arrays are. So in the strict, .NET specific way, a String is not an Array.
2)然而,正如其他人所指出的那样,弦乐有点奇怪。它不是所有其他数组的System.Array。因此,在严格的.NET特定方式中,String不是数组。
#1
17
System.String is not a .NET array of Char because this:
System.String不是Char的.NET数组,因为这样:
char[] testArray = "test".ToCharArray();
testArray[0] = 'T';
will compile, but this:
将编译,但这:
string testString = "test";
testString[0] = 'T';
will not. Char arrays are mutable, Strings are not. Also, string is Array
returns false, while char[] is Array
returns true.
将不会。字符串数组是可变的,字符串不是。另外,string是Array返回false,而char []是Array返回true。
#2
14
No, it's not an array. But it does have an indexer. Best of both worlds.
不,这不是阵列。但它确实有一个索引器。两全其美。
#3
5
Strings in .NET are backed by the System.String
class, which internally uses a bunch of unsafe methods to do pointer manipulation on the actual string data using standard C memory manipulation techniques.
.NET中的字符串由System.String类支持,该类在内部使用一堆不安全的方法,使用标准的C内存操作技术对实际的字符串数据进行指针操作。
The String
class itself does not contain an array, but it does have an indexer property which allows you to treat the data as if it were an array.
String类本身不包含数组,但它有一个indexer属性,允许您将数据视为数组。
#4
3
No, String is a class in .Net. It may be backed by an array. but it is not an array. Classes can have indexers, and that is what String is doing.
不,String是.Net中的一个类。它可能由数组支持。但它不是一个数组。类可以有索引器,这就是String正在做的事情。
See comments for elaboration on this statement: From what I understand, all strings are stored in a common blob. Because of this, "foo" and "foo" point to the same point in that blob... one of the reasons strings are immutable in C#.
请参阅有关此声明的详细说明:根据我的理解,所有字符串都存储在一个公共blob中。因此,“foo”和“foo”指向该blob中的相同点...字符串在C#中不可变的原因之一。
#5
2
A string
is not a char[]
, although it does have a .ToCharArray()
. Also it does have an indexer, which allows you to access characters individually, like you've shown. It is likely that it was implemented with an array internally, but that's an implementation detail.
字符串不是char [],尽管它有一个.ToCharArray()。它还有一个索引器,它允许你单独访问字符,就像你已经显示的那样。它可能是在内部使用数组实现的,但这是一个实现细节。
#6
2
A string object contains a continuous block of characers, just like an array of characters, but the string object neither is, nor contains an array object.
字符串对象包含一个连续的characers块,就像字符数组一样,但字符串对象既不是,也不包含数组对象。
The compiler knows that the string string is immutable, so it can do certain optimisations when you access a string, in the same manner that it does optimisations when you access an array. So, when you access a string by index, it's likely that the code ends up accessing the string data directly rather than calling an indexer property.
编译器知道字符串字符串是不可变的,因此在访问字符串时它可以执行某些优化,其方式与访问数组时的优化方式相同。因此,当您通过索引访问字符串时,代码可能最终直接访问字符串数据而不是调用索引器属性。
#7
2
To add a little to Scott Dorman's and Gufa's answer. If you use Windbg and !DumpObject on the string 'abcd' you'll get somthing like this.
添加一点Scott Dorman和Gufa的答案。如果你在字符串'abcd'上使用Windbg和!DumpObject,你会得到这样的东西。
0:000> !do 01139b24
Name: System.String
MethodTable: 79330a00
EEClass: 790ed64c
Size: 26(0x1a) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: abcd
Fields:
MT Field Offset Type VT Attr Value Name
79332c4c 4000096 4 System.Int32 1 instance 5 m_arrayLength
79332c4c 4000097 8 System.Int32 1 instance 4 m_stringLength
793316e0 4000098 c System.Char 1 instance 61 m_firstChar
79330a00 4000099 10 System.String 0 shared static Empty
>> Domain:Value 00181b38:01131198 <<
79331630 400009a 14 System.Char[] 0 shared static WhitespaceChars
>> Domain:Value 00181b38:011318b8 <<
You'll notice its only got three instance fields. m_arrayLength, m_stringLength and m_firstChar. It does not contain an instance System.Char[] The other 2 fields are static shared so every System.String has the same Empty string and WhitespaceChar Char Array.
你会注意到它只有三个实例字段。 m_arrayLength,m_stringLength和m_firstChar。它不包含实例System.Char []其他2个字段是静态共享的,因此每个System.String都具有相同的空字符串和WhitespaceChar字符数组。
If you follow that with a DumpByte you'll see the string data (in this case abcd) that's in the heap which of course starts at offset 0x0c (m_firstChar) and is 8 bytes wide (m_stringLength 4 x 2 for unicode).
如果您使用DumpByte,您将看到堆中的字符串数据(在本例中为abcd),当然从偏移量0x0c(m_firstChar)开始,宽度为8字节(对于unicode,m_stringLength为4 x 2)。
0:000> db 01139b24 L1A
01139b24 00 0a 33 79 05 00 00 00-04 00 00 00 61 00 62 00 ..3y........a.b.
01139b34 63 00 64 00 00 00 00 00-00 00 c.d......
If you were to look in the SSCLI you'll see that it, as Scott says, either runs unsafe code and uses pointer techniques to read the data using the m_firstChar and the m_stringLength.
如果您要查看SSCLI,您会看到它,正如Scott所说,它运行不安全的代码并使用指针技术使用m_firstChar和m_stringLength读取数据。
#8
2
String is a class which takes an array of char to initialized itself, So when you try to fetch the element at some index it returns char. Check the string class
String是一个类,它接受一个char数组来自己初始化,所以当你尝试在某个索引处获取元素时,它返回char。检查字符串类
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
{
// Summary:
// Initializes a new instance of the System.String class to the value indicated
// by an array of Unicode characters.
//
// Parameters:
// value:
// An array of Unicode characters.
[SecuritySafeCritical]
public String(char[] value);
}
Also see String class declaration.
另请参见String类声明。
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
Which is inherited by IEnumerable<char>
.
哪个由IEnumerable
Inside the string class there is a get property which returns the char when index is passed, see the image. Which clearly says that Gets the System.Char object at a specified position in the current System.String
在字符串类中有一个get属性,它在传递索引时返回char,请参见图像。这清楚地说明了在当前System.String中的指定位置获取System.Char对象
public char this[int index] { get; }
#9
1
A string
is not an array of char
s until you convert it to one. The notation is simply used to access characters at different positions (indices) in a string.
在将字符串转换为字符串之前,字符串不是字符数组。该表示法仅用于访问字符串中不同位置(索引)的字符。
#10
1
Using Reflector, we can see that string does implement IEnumerable<char>
. So, it is not a character array, but in essence can be used like one.
使用Reflector,我们可以看到字符串确实实现了IEnumerable
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
EDIT:
编辑:
Implementing IEnumerable<char>
does not mean that the type will be indexed. I didn't mean to convey that. It means that you can enumerate over it and use it like a collection. A better way of wording what I meant to say is that a string isn't a character array, but is a collection of characters. Thanks for the comment.
实现IEnumerable
#11
1
Strings is simply not an array, in the sense that "Hello" is char[]
is evaluated to false
.
字符串根本不是数组,因为“Hello”是char []被评估为false。
#12
0
Everyone has given half the answer, so here is both parts:
每个人都给出了一半的答案,所以这里有两个部分:
1) Strictly speaking, yes, a String in .NET is an array of characters. It is so both in its internal implementation, and by the symantic definition of an array.
1)严格来说,是的,.NET中的String是一个字符数组。它的内部实现和数组的语义定义都是如此。
2) However String is, as others have pointed out, somewhat peculiar. It is not a System.Array as all other arrays are. So in the strict, .NET specific way, a String is not an Array.
2)然而,正如其他人所指出的那样,弦乐有点奇怪。它不是所有其他数组的System.Array。因此,在严格的.NET特定方式中,String不是数组。