2010-09-24 27 views
5

Tôi chỉ muốn chắc chắn:đại diện nội bộ của chuỗi trong C#

string x = ""; 
char Char = x[0]; // throws exception: "Index was outside the bounds of the array" 

Điều này có nghĩa rằng chuỗi thực sự là đối xử như một mảng các ký tự, phải không? (Ít nhất là nội bộ.)

Trả lời

6

mỗi @JaredPar elsewhere on this site:

Chuỗi underyling bạn tạo sẽ cũng cần một khối liền kề bộ nhớ bởi vì nó được thể hiện dưới dạng một mảng của chars (mảng đòi hỏi tiếp giáp với bộ nhớ ).

tôi chắc chắn bạn không nên dựa vào điều này vì nó không phải là một phần của giao diện , nhưng thực hiện là một mảng nếu tuyên bố này là đúng. Điều đó có ý nghĩa với tôi khi đưa ra những gì chúng ta biết về chuỗi ký tự và nhu cầu của Microsoft để hỗ trợ interop hiệu quả giữa các ngôn ngữ được quản lý và ngôn ngữ bản địa.

MSDN chỉ nói điều này, điều này không đảm bảo rằng bộ nhớ là một mảng.

Chuỗi là tập hợp tuần tự Ký tự Unicode được sử dụng để đại diện cho văn bản. Đối tượng String là một bộ sưu tập tuần tự của các đối tượng System.Char đại diện cho một chuỗi. Giá trị của đối tượng Chuỗi là nội dung của bộ sưu tập tuần tự, và giá trị đó là không thay đổi (nghĩa là, là chỉ đọc).

+0

+1 cho câu trả lời rõ ràng, được ghi nhận. – NotMe

13

Thông số ngôn ngữ C# không đảm bảo về biểu diễn bên trong của chuỗi. Tuy nhiên, nó thực hiện toán tử chỉ mục để cung cấp một char cho mỗi ký tự trong chuỗi.

Chỉnh sửa: Để làm rõ vì một vài người đã nhận xét, có, biểu diễn bên trong của System.String trong CLR là một mảng. Tuy nhiên, đặc tả ngôn ngữ không nói bất cứ điều gì về biểu diễn nội bộ, do đó, điều này có thể (nhưng không có khả năng) thay đổi. Nó nói rằng một chuỗi phải hoạt động như một chuỗi các ký tự. Chỉ một chút về điều này trong thông số ngôn ngữ là theo phần 1.3:

Ký tự và xử lý chuỗi trong C# sử dụng mã hóa Unicode. Kiểu char đại diện cho một đơn vị mã UTF-16 và loại chuỗi biểu thị một chuỗi các đơn vị mã UTF-16.

Bên cạnh đó, MSDN trạng thái:

Một chuỗi là một bộ sưu tập tuần tự của các ký tự Unicode được sử dụng để đại diện cho văn bản. Một đối tượng String là một tập hợp tuần tự các đối tượng System.Char biểu diễn một chuỗi. Giá trị của đối tượng String là nội dung của bộ sưu tập tuần tự, và giá trị đó là không thay đổi (có nghĩa là, nó là chỉ đọc).

Vì vậy, trong trường hợp này, chúng tôi hiện đang nói về CLR chứ không phải ngôn ngữ. System.String - Tuy nhiên, ngay cả khi họ không đảm bảo một mảng, chỉ có một bộ sưu tập tuần tự.

Một chuỗi được triển khai với danh sách được liên kết và một người lập chỉ mục đã di chuyển n dấu cách chuyển tiếp trong danh sách sẽ đủ để đáp ứng các yêu cầu về ngôn ngữ. IList<char> cũng sẽ đáp ứng các yêu cầu và IList không cần phải được hỗ trợ theo mảng.

+7

@Bear Monkey - 'bộ sưu tập tuần tự' không giống như 'mảng'. Bạn nên rút lại ý kiến ​​của mình. –

+1

Hạn chế duy nhất trong tài liệu ECMA quy chuẩn nói về bộ đệm ký tự, không cụ thể là cá thể System.Array: Triển khai Hệ thống.Chuỗi bắt buộc phải chứa bộ đệm ký tự có độ dài thay đổi được định vị một số byte cố định sau phần đầu của đối tượng Chuỗi. –

+0

Ông không nói mảng ông nói nó không đảm bảo về đại diện nội bộ. Nhưng điều này không đúng. –

1

Bạn có thể tìm thấy điều này MSDN doc hữu ích.

Tóm lại, một chuỗi được "lưu trữ như một tuần tự thu read-only của Char đối tượng"

Và, vâng, nó có thể được truy cập giống như một mảng char. Vì vậy, nếu X chứa một giá trị khác với String.Empty, thì mã char Char=X[0;] sẽ trả về ký tự đầu tiên của chuỗi.

1

C# chỉ là ngôn ngữ. Từ khóa chuỗi là một bí danh cho System.String trong BCL của .Net framework. Nó là khá an toàn để giả định rằng nội String là một mảng của ký tự. Từ MSDN:

Chuỗi là tập hợp tuần tự các ký tự Unicode được sử dụng để biểu diễn văn bản. Một đối tượng String là một tập hợp tuần tự các đối tượng System.Char biểu diễn một chuỗi.

0

Điều đó tùy thuộc vào ý nghĩa của từ "mảng".

Nếu bạn muốn nói khái niệm tính toán chung của một đối tượng truy cập ngẫu nhiên, độ dài cố định, các đối tượng có thể lập chỉ mục nguyên, thì có, một chuỗi có thể được xem chính xác như vậy. (Khái niệm tính toán chung thường bao gồm tiếp giáp trong bộ nhớ, nhưng chặn một vài trường hợp, chẳng hạn như sử dụng con trỏ trong mã không an toàn, điều đó không có ý nghĩa lắm về C#).

Nếu bạn có nghĩa là ngôn ngữ C# thực hiện khái niệm này, char[] sau đó không thực sự, hai là những thứ khác nhau.

Trong thực tế, System.String thực sự được triển khai dưới dạng một mảng char s, nhưng không nhất thiết phải như vậy.

Ngôn ngữ nit-picks sang một bên, các bit thực hiện:

Nếu bạn muốn làm các thao tác tương tự trên một chuỗi như bạn làm trên một char[] thì đây thường sẽ làm việc (đặc biệt là mặc dù, chuỗi được read-only) và thường là cách hiệu quả nhất để làm như vậy, miễn là khái niệm khá đơn giản. Cụ thể, sử dụng foreach và sử dụng chỉ mục di chuyển giữa các số 0str.Length - 1 hoạt động tốt. Tương tự, rất nhiều hoạt động mà một người có thể thực hiện trên char[] có thể được thực hiện trên string, chẳng hạn như CopyTo() và truyền tới IEnumerable<char>.

Nếu bạn muốn thực sự có một mảng ký tự thì bạn cần gọi ToCharArray().

Các vấn đề liên quan