Câu hỏi Sự khác nhau giữa Chuỗi và chuỗi trong C # là gì?


Thí dụ (lưu ý trường hợp):

string s = "Hello world!";
String s = "Hello world!";

Là những gì hướng dẫn cho việc sử dụng của mỗi? Và cái gì sự khác biệt?


5362


gốc


@ O.R.Mapper, nhưng thực tế vẫn là string là một từ vựng cấu trúc của C # ngữ pháp trong khi System.String chỉ là một loại. Bất kể bất kỳ rõ ràng sự khác biệt được đề cập trong bất kỳ thông số kỹ thuật nào, vẫn có sự khác biệt tiềm ẩn này có thể chứa đựng một số sự mơ hồ. Bản thân ngôn ngữ phải ủng hộ string theo một cách mà việc thực hiện không phải là (khá) vì vậy bắt buộc phải xem xét cho một lớp học cụ thể trong BCL. - Kirk Woll
@KirkWoll: Theo đặc tả ngôn ngữ, chính ngôn ngữ đó phải xem xét string chính xác giống như loại BCL System.String, không có gì khác. Đó không phải là mơ hồ chút nào. Tất nhiên, bạn có thể thực hiện trình biên dịch của riêng bạn, sử dụng ngữ pháp C #, và sử dụng tất cả các thẻ được tìm thấy như thế cho một cái gì đó tùy ý, không liên quan đến những gì được định nghĩa trong đặc tả ngôn ngữ C #. Tuy nhiên, ngôn ngữ kết quả sẽ chỉ là một C # giống nhau, nó không thể được coi là C #. - O. R. Mapper
Bạn có thể dùng string mà không sử dụng chỉ thị cho Hệ thống. Bạn không thể làm điều đó với String. - Wilsu
Đối với một người đến từ Algol và Fortran, cuộc thảo luận này cho thấy có điều gì đó sai trái với string. Nó là cần thiết để viết tắt System.String, nhưng, như một bí danh, nó có vẻ khá giống, nhưng không hoàn toàn giống nhau. Sau vài năm của C #, mặc dù, tôi muốn nói, nó là an toàn để chỉ đơn giản là sử dụng string và string.Format() và không phải lo lắng về System.String. - Roland
Nếu loại câu hỏi này được hỏi vào năm 2017, nó sẽ nhận được 4.000 phiếu giảm giá, 2.000 liên kết đến trang lớp chuỗi MSDN và đóng cửa không hiệu quả. - IRGeekSauce


Các câu trả lời:


string là một bí danh trong C # cho System.String.
Vì vậy, về mặt kỹ thuật, không có sự khác biệt. Nó giống như int  so với  System.Int32.

Theo hướng dẫn, thường được khuyến nghị sử dụng string bất cứ lúc nào bạn đang đề cập đến một đối tượng.

ví dụ.

string place = "world";

Tương tự như vậy, tôi nghĩ rằng nó thường được khuyến khích sử dụng String nếu bạn cần tham khảo cụ thể cho lớp học.

ví dụ.

string greet = String.Format("Hello {0}!", place);

Đây là phong cách mà Microsoft có xu hướng sử dụng ví dụ của họ.

Có vẻ như hướng dẫn trong khu vực này có thể đã thay đổi, vì StyleCop bây giờ thực thi việc sử dụng các bí danh cụ thể C #.


5097



Nếu bạn quyết định sử dụng StyleCop và làm theo đó, điều đó sẽ nói để sử dụng các loại cụ thể cho ngôn ngữ. Vì vậy, đối với C # bạn sẽ có chuỗi (thay vì String), int (thay vì Int32), float (thay vì Single) - stylecop.soyuz5.com/SA1121.html - Dominic Zukiewicz
Tôi luôn luôn sử dụng bí danh vì tôi đã giả định một ngày nó có thể có ích bởi vì chúng hoạt động như một trừu tượng, do đó có thể thay đổi triển khai của chúng mà không cần phải biết. - Rob
Visual Studio 2015 nói rằng String.Format nên được thay đổi thành string.Format, vì vậy tôi đoán Microsoft đang đi theo cách đó. Tôi cũng luôn sử dụng String cho các phương thức tĩnh. - Sami Kuhmonen
Như tôi đã đọc qua những thông báo này, tôi nhận thấy một số nhận xét đơn giản là không chính xác. @ DRAirey1 Trong thời gian, bạn sẽ thấy rằng cách cũ vẫn là tốt nhất, nếu bạn nghi ngờ rằng sau đó tôi dám bạn cố gắng viết mã C # mà không cần sử dụng Visual Studio. Đó là hầu như không thể và một tình huống mà đi lên theo thời gian trong công việc phát triển web. @Vlad Bạn không cần nhập bất cứ thứ gì để sử dụng String. @Abhi Cảm nhận của bạn là vô nghĩa và bình đẳng cho string.Format(). @ KlitosG Không, điều đó không đúng. Tất cả chúng đều hoạt động giống nhau. - krowe2
Bạn có thể thêm một nhận xét rằng có, trên thực tế, một sự khác biệt? Ví dụ: nameof(string) sẽ không biên dịch trong khi nameof(String) sẽ. - Jeroen Vannevel


Chỉ vì lợi ích của sự hoàn chỉnh, đây là một bãi chứa não của thông tin liên quan ...

Như những người khác đã lưu ý, string là bí danh cho System.String. Chúng biên dịch cho cùng một mã, do đó, tại thời gian thực hiện không có sự khác biệt nào. Đây chỉ là một trong các bí danh trong C #. Danh sách đầy đủ là:

object:  System.Object
string:  System.String
bool:    System.Boolean
byte:    System.Byte
sbyte:   System.SByte
short:   System.Int16
ushort:  System.UInt16
int:     System.Int32
uint:    System.UInt32
long:    System.Int64
ulong:   System.UInt64
float:   System.Single
double:  System.Double
decimal: System.Decimal
char:    System.Char

Ngoài string và object, các bí danh là tất cả các loại giá trị. decimal là một loại giá trị, nhưng không phải là một kiểu nguyên thủy trong CLR. Loại nguyên thủy duy nhất không có bí danh là System.IntPtr.

Trong spec, các bí danh kiểu giá trị được gọi là "các kiểu đơn giản". Literals có thể được sử dụng cho các giá trị không đổi của mọi kiểu đơn giản; không có loại giá trị nào khác có sẵn các dạng chữ. (So ​​sánh điều này với VB, cho phép DateTime literals, và có một bí danh cho nó quá.)

Có một trường hợp mà bạn  để sử dụng bí danh: khi chỉ định rõ ràng loại cơ bản của enum. Ví dụ:

public enum Foo : UInt32 {} // Invalid
public enum Bar : uint   {} // Valid

Đó chỉ là vấn đề của cách mà spec xác định khai báo enum - phần sau dấu hai chấm phải là không thể tách rời sản xuất, đó là một dấu hiệu của sbyte, byte, short, ushort, int, uint, long, ulong, char... trái ngược với kiểu sản xuất như được sử dụng bởi các tờ khai biến chẳng hạn. Nó không chỉ ra bất kỳ sự khác biệt nào khác.

Cuối cùng, khi nói đến đó để sử dụng: cá nhân tôi sử dụng bí danh ở khắp mọi nơi để thực hiện, nhưng loại CLR cho bất kỳ API. Nó thực sự không quan trọng quá nhiều mà bạn sử dụng trong điều khoản của việc thực hiện - nhất quán trong nhóm của bạn là tốt đẹp, nhưng không ai khác sẽ chăm sóc. Mặt khác, điều thực sự quan trọng là nếu bạn đề cập đến một loại trong API, bạn làm như vậy theo cách trung lập ngôn ngữ. Một phương pháp gọi là ReadInt32 là rõ ràng, trong khi một phương pháp được gọi là ReadInt yêu cầu thông dịch. Người gọi có thể đang sử dụng ngôn ngữ xác định int bí danh cho Int16, ví dụ. Các nhà thiết kế khuôn khổ .NET đã tuân theo mẫu này, các ví dụ tốt đang ở trong BitConverter, BinaryReader và Convert các lớp học.


3037



Tình trạng thừa kế với enum là thú vị. Bạn có thể trỏ đến tài liệu hướng dẫn về lý do tại sao bí danh phải được sử dụng cho các bảng liệt kê? Hay đây là một lỗi đã biết? - JaredPar
Đó là trong phần 14.1 của spec (Tôi không thể trích dẫn ở đây dễ dàng vì nó quá dài). Nó không rõ ràng nói rằng bạn phải sử dụng bí danh, nhưng bí danh là loại được coi là loại riêng của họ. Đó là tất cả một chút lạ. - Jon Skeet
@PiPeep những gì đáng kinh ngạc hơn số lượng lớn upvotes là số tiền đáng kinh ngạc thấp của downvotes (xem xét 5 bài viết hàng đầu có tổng cộng hơn 2000 upvotes, và chỉ có 1 downvote trong số tất cả). Đặc biệt là khi bạn yếu tố trong quan niệm rằng luôn luôn có "kẻ thù" trong bất kỳ cộng đồng nào, tôi thực sự thấy điều đó thật đáng kinh ngạc. - corsiKa
Một sự khác biệt thú vị giữa string và String đó là string' is a keyword in c#, so you can not use it as a variable name.For Ex: string string = "hi";//compiler error, but Chuỗi chuỗi = "hi"; `được chấp nhận, như String là một từ định danh không phải là từ khóa. - Sanjeev Rai
@SanjeevRai: Có. Bạn có thể dùng @string để tạo một số nhận dạng kết thúc bằng string Tuy nhiên. Đó là một loại cơ chế thoát. - Jon Skeet


String viết tắt của System.String và nó là một kiểu .NET Framework. string là bí danh bằng ngôn ngữ C # cho System.String. Cả hai đều được biên dịch System.String trong IL(Ngôn ngữ trung gian), do đó, không có sự khác biệt. Chọn những gì bạn thích và sử dụng nó. Nếu bạn viết mã trong C #, tôi thích string vì đó là bí danh loại C # và được các lập trình viên C # nổi tiếng.

Tôi có thể nói như vậy về (int, System.Int32) v.v.


608



`Nếu bạn mã trong C #, tôi thích chuỗi vì nó là một bí danh kiểu C # và nổi tiếng bởi các lập trình viên C # - khi nào một người C # không biết .NET framework. 1 như tôi nghĩ rằng đây là câu trả lời hay nhất, nhưng điểm tôi đề cập có vẻ kỳ quặc. - MyDaftQuestions
Cá nhân tôi thích sử dụng "Int32", vì nó ngay lập tức cho thấy phạm vi của giá trị. Hãy tưởng tượng nếu họ nâng cấp loại "int" trên các hệ thống cao hơn sau này. 'int' trong c được xem là "loại số nguyên mà bộ xử lý mục tiêu hiệu quả nhất khi làm việc với"và được định nghĩa là "ít nhất 16 bit". Tôi thích sự nhất quán có thể đoán trước ở đó, cảm ơn bạn rất nhiều. - Nyerguds
@MyDaftQuestions Tôi đồng ý. Nếu bất cứ điều gì nó có ý nghĩa với luôn sử dụng các loại .net bởi vì chúng là ngôn ngữ dốt nát và loại là hiển nhiên, độc lập với bất kỳ ngôn ngữ nào (tôi có biết tất cả các tính đồng nhất của F # hay VB không?). - Peter A. Schneider


Câu trả lời hay nhất mà tôi từng nghe về việc sử dụng bí danh loại được cung cấp trong C # xuất phát từ Jeffrey Richter trong cuốn sách của anh ấy CLR Qua C #. Dưới đây là 3 lý do của anh ấy:

  • Tôi đã thấy một số nhà phát triển nhầm lẫn, không biết liệu có nên sử dụng hay không chuỗi hoặc là Chuỗi trong mã của họ. Bởi vì trong C # chuỗi (một từ khóa) ánh xạ chính xác đến System.String (một loại FCL), không có sự khác biệt và có thể được sử dụng.
  • Trong C #, Dài bản đồ đến System.Int64, nhưng bằng một ngôn ngữ lập trình khác, Dài có thể ánh xạ tới Int16 hoặc là Int32. Trên thực tế, C ++ / CLI thực sự coi như là một Int32. Ai đó đọc mã nguồn bằng một ngôn ngữ có thể dễ dàng hiểu sai ý định của mã nếu người đó đã quen với việc lập trình bằng ngôn ngữ lập trình khác. Trên thực tế, hầu hết các ngôn ngữ thậm chí sẽ không xử lý Dài làm từ khóa và sẽ không biên dịch mã sử dụng nó.
  • FCL có nhiều phương thức có tên kiểu như là một phần của tên phương thức của chúng. Ví dụ: BinaryReader loại cung cấp các phương pháp như ReadBoolean, ReadInt32, ReadSingle, v.v. và System.Convert loại cung cấp các phương pháp như ToBoolean, ToInt32, ToSingle, v.v. Mặc dù nó là hợp pháp để viết đoạn mã sau, dòng với float cảm thấy rất không tự nhiên với tôi, và nó không rõ ràng rằng dòng là chính xác:
BinaryReader br = new BinaryReader(...);
float val  = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good

Vì vậy, có bạn có nó. Tôi nghĩ rằng đây là tất cả những điểm thực sự tốt. Tuy nhiên, tôi không tìm thấy bản thân mình bằng cách sử dụng lời khuyên của Jeffrey trong mã của riêng tôi. Có lẽ tôi quá mắc kẹt trong thế giới C # của mình nhưng cuối cùng tôi lại cố gắng làm cho mã của tôi trông giống như mã khung.


411



Điểm thứ hai âm thanh thực sự giống như một lý do không phải sử dụng string, int v.v. - MauganRa
@MauganRa Và nó được cho là, tác giả của cuốn sách liệt kê những lý do đó là tại sao anh ta không sử dụng bí danh. - tomi.lee.jones
"Nếu ai đó đang đọc mã nguồn C # thì họ nên diễn giải lâu dài theo đặc tả ngôn ngữ, chứ không phải thông số ngôn ngữ khác". Điều đó bỏ lỡ điểm hoàn toàn. Không phải ai dự định để giải thích sai mã, đơn giản là dễ dàng cho bộ não của một người nhảy đến kết luận sai lầm khi một loại có ý nghĩa khác với ý nghĩa của lập trình viên hàng ngày trong ngữ cảnh khác. Tất cả chúng ta đều phạm sai lầm; sử dụng các loại được đặt tên rõ ràng làm cho những lỗi đó ít có khả năng xảy ra hơn. - Darryl
+ Những lý do này tổng hợp cảm xúc của tôi về vấn đề này. Khi tôi lần đầu tiên bắt đầu viết mã trong C # (đến từ một nền Java / C ++ / C), tôi nghĩ rằng các bí danh là xấu xí. Tôi vẫn cảm thấy như vậy, tiếc là hầu hết thế giới dường như không đồng ý với tôi, hoặc họ không quan tâm, và vì vậy hãy sử dụng chữ thường. - gusgorman
@jinzai câu hỏi là về C #, trong đó long được định nghĩa là số nguyên 64 bit đã ký, bất kể nền tảng hoặc trình biên dịch. Vì vậy, trong một số trường hợp ít nhất, có, nó làm phụ thuộc vào ngôn ngữ. - phoog


string là một từ dành riêng, nhưng String chỉ là một tên lớp. Điều này có nghĩa rằng string không thể được sử dụng như một tên biến của chính nó.

Nếu vì lý do nào đó bạn muốn có một biến gọi là chuỗi, bạn sẽ chỉ thấy bản biên dịch đầu tiên sau:

StringBuilder String = new StringBuilder();  // compiles
StringBuilder string = new StringBuilder();  // doesn't compile 

Nếu bạn thực sự muốn có một tên biến được gọi là chuỗi bạn có thể dùng @ làm tiền tố:

StringBuilder @string = new StringBuilder();

Một sự khác biệt quan trọng: Stack Overflow làm nổi bật chúng một cách khác nhau.


380



Xin lưu ý rằng hãy gọi cho một địa phương @string thực sự là vô nghĩa, vì tên của người dân địa phương chỉ có mặt trong PDB. Cũng có thể gọi nó _string hay gì đó. Nó có ý nghĩa hơn cho những thứ có tên có thể truy cập thông qua sự phản ánh, tên của một @string thành viên sẽ là "string". - Roman Starkov
Cũng nên nhớ sử dụng một từ dành riêng như một tên biến là vô lương tâm. - Elton
"tràn ngăn xếp làm nổi bật chúng một cách khác nhau". Không cần thêm lý do :) - Ole Albers
OP không muốn sử dụng chuỗi hoặc chuỗi dưới dạng tên biến. Họ yêu cầu giải thích về sự khác biệt giữa các Các loại. Câu trả lời của bạn chỉ phục vụ để thêm nhiều sự nhầm lẫn IMO - Matt Wilko


Có một sự khác biệt - bạn không thể sử dụng String không có using System; trước.


327



theo mặc định, hầu hết mọi người làm điều này bằng bất kỳ cách nào ở đầu tệp. VS thực hiện điều này theo mặc định trong hầu hết các trường hợp không phải tất cả! - IbrarMumtaz
Theo mặc định, tôi chỉ thêm using tuyên bố tôi yêu cầu, và loại bỏ một cách rõ ràng tất cả những gì tôi không. Công cụ hiệu suất năng lượng> "[x] Xóa và định dạng sử dụng khi lưu" - JMD
@ JMD Tôi đã sửa đổi tệp mẫu .cs để nó thậm chí không có bất kỳ câu lệnh nào sử dụng ở trên cùng! Tôi cũng đã thay đổi mẫu lớp thành internal sealed. - ErikE


Nó đã được đề cập ở trên; tuy nhiên, bạn không thể sử dụng string trong sự phản chiếu; bạn phải dùng String.


269





System.String là lớp chuỗi .NET - trong C # string là bí danh cho System.String - để sử dụng chúng giống nhau.

Đối với các hướng dẫn, tôi sẽ không nhận được quá bogged xuống và chỉ sử dụng bất cứ điều gì bạn cảm thấy như - có những điều quan trọng hơn trong cuộc sống và mã sẽ là như nhau anyway.

Nếu bạn thấy mình xây dựng hệ thống, nơi nó là cần thiết để xác định kích thước của các số nguyên bạn đang sử dụng và do đó có xu hướng sử dụng Int16, Int32, UInt16, UInt32 v.v. thì có vẻ tự nhiên hơn khi sử dụng String- và khi di chuyển giữa các ngôn ngữ .net khác nhau, nó có thể làm cho mọi thứ dễ hiểu hơn - nếu không tôi sẽ sử dụng chuỗi và int.


204



1 cho biết rằng có những điều quan trọng hơn trong cuộc sống, tôi cảm thấy ở đây là một StackOverflow hàng triệu câu hỏi upvote về một không đáng kể vấn đề đang diễn ra: en.wikipedia.org/wiki/Parkinson's_law_of_triviality - Sebastian
Chỉ cần chọn một và nhất quán. Nếu bạn làm việc ở đâu đó với kiểu nhà, hãy sử dụng nó. - Alan B
phong cách không may là sở thích cá nhân và có thể quá tốn kém để thực thi trong một cơ sở mã lớn trên nhiều nhóm mà không có chủ sở hữu mã chuyên dụng. luôn có những vấn đề quan trọng hơn để chăm sóc thay vì chuỗi so với Chuỗi. đưa chúng ta trở lại "những điều quan trọng hơn trong cuộc sống" - aiodintsov


Tôi thích viết hoa hơn .NET các loại (chứ không phải là bí danh) vì lý do định dạng. Các .NET các kiểu được tô màu giống như các kiểu đối tượng khác (các kiểu giá trị là các đối tượng thích hợp, sau khi tất cả).

Từ khóa có điều kiện và kiểm soát (như if, switchreturn) là chữ thường và màu xanh đậm (theo mặc định). Và tôi không muốn có sự bất đồng trong sử dụng và định dạng.

Xem xét:

String someString; 
string anotherString; 

167



Bạn cũng viết mã như: Int32 i = 1; Thay vì int i = 1; ? Có vẻ không nhất quán khi không sử dụng bí danh chuỗi khi có sẵn. - bytedev
@nashwan: thực sự, vâng, tôi sử dụng Int32 i=1; intstead của int i = 1;  Tôi tìm thấy các cựu để được dễ đọc hơn như ý định của tôi: cụ thể là tôi muốn có một số nguyên 32 bit đã ký. - NotMe
Vâng, tôi đoán tất cả phụ thuộc vào việc các nhà phát triển nghĩ rằng họ đang viết mã C # (chuỗi) hoặc mã .NET (String). Cá nhân tôi nghĩ rằng tôi đang viết C # (và đó là C # đang sử dụng .NET). - bytedev
@ Alex: quan điểm của tôi đơn giản là tôi thích rất cụ thể trong mã hóa của tôi để loại bỏ sự mơ hồ. - NotMe
Ở đầu kia, tôi gần như luôn sử dụng var - tic


string và String giống hệt nhau (ngoại trừ chữ hoa "S"). Không có tác động hiệu quả nào cả.

Chữ thường string được ưa thích trong hầu hết các dự án do tô sáng cú pháp


166



Jeffrey Richter khuyến nghị sử dụng kiểu CLR trong mọi trường hợp (CLR qua C #) để tránh chính xác loại nhầm lẫn đang diễn ra ở đây. - Josh
Rõ ràng, cho dù bạn sử dụng S hay s nó sẽ gây ra câu hỏi này, vì vậy hãy bỏ phiếu cho Richter. ;) - Brad Wilson
Richter có nghĩa là chuỗi đó không phải là một lựa chọn - Microsoft không nên có nó bằng ngôn ngữ. Bạn không thể bỏ phiếu cho Richter - anh ấy là một huyền thoại! :) - Joe Ratzer
Điểm công bằng Jon, nhưng tôi chỉ tình cờ đồng ý với Richter về điểm này về Chuỗi. Và có, tôi hoàn toàn đồng ý - CLR qua C # thật tuyệt vời! - Joe Ratzer
"chuỗi" không giống như "Chuỗi". Có nghĩa là "System.String". Vì vậy, nếu bạn sử dụng "String", bạn phải đặt "using System" để bao gồm namespace - ThiagoAlves


C # là một ngôn ngữ được sử dụng cùng với CLR.

string là một loại trong C #.

System.String là một loại trong CLR.

Khi bạn sử dụng C # cùng với CLR string sẽ được ánh xạ tới System.String.

Về mặt lý thuyết, bạn có thể thực hiện một C # -compiler tạo ra bytecode Java. Một thực hiện hợp lý của trình biên dịch này có lẽ sẽ là bản đồ string đến java.lang.String để tương thích với thư viện thời gian chạy Java.


154



string Không phải là kiểu trong C #; nó là một từ dành riêng để ánh xạ tới một kiểu trong CLR. - CesarGon
@ CesarGon: Theo ECMA-334, mục 8.2.1: "C # cung cấp một tập hợp các kiểu được xác định trước [...] Các kiểu tham chiếu được xác định trước là đối tượng và chuỗi." - Rasmus Faber
Theo ECMA-334, mục 9.4.3, "chuỗi" là một từ khóa. :-) Tôi đồng ý với bạn rằng "chuỗi" là một loại nếu bạn tập trung vào ngữ nghĩa, nhưng tôi muốn nói đó là một từ khóa (tức là một từ dành riêng) nếu bạn tập trung vào cú pháp. Tiêu chuẩn ủng hộ cả hai quan điểm (có lẽ quá mơ hồ!). Đối với tôi, OP là về cú pháp, vì vậy tôi có xu hướng tập trung vào cú pháp khi tôi nhìn vào câu trả lời, nhưng tôi cũng thấy quan điểm của bạn. Hơn nữa, câu trả lời của bạn, như nó đứng, có thể được hiểu là có nghĩa là hai loại khác nhau tồn tại: string và String, khi đó không phải là trường hợp. Một là bản đồ cho người khác. - CesarGon
Hãy rõ ràng về điều này. 'chuỗi' là bí danh được đặt trước. Nó không phải là một kiểu dữ liệu thực sự. Nó là cái gì đó trỏ đến cái gì khác. Bạn có thể loại bỏ tất cả các bí danh này (hoặc không bao giờ sử dụng chúng) và có một ngôn ngữ lập trình hoàn hảo tốt. - Mike Doonsebury