Apa perbedaan antara String dan string dalam C #?

6511

Contoh ( perhatikan kasusnya ):

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

Apa pedoman untuk penggunaan masing-masing? Dan apa perbedaannya?

Peter O.
sumber
72
@ORMapper, tetapi faktanya tetap stringmerupakan konstruksi leksikal dari tata bahasa C # sedangkan System.Stringhanya tipe. Terlepas dari perbedaan eksplisit yang disebutkan dalam spesifikasi apa pun, masih ada perbedaan implisit yang dapat diakomodasi dengan beberapa ambiguitas. Bahasa itu sendiri harus mendukung stringdengan cara yang implementasi tidak (cukup) jadi wajib untuk mempertimbangkan untuk kelas tertentu di BCL.
Kirk Woll
106
@KirkWoll: Menurut spesifikasi bahasa, bahasa itu sendiri harus mempertimbangkan stringpersis sama dengan tipe BCL System.String, tidak ada yang lain. Itu sama sekali tidak ambigu. Tentu saja, Anda dapat mengimplementasikan kompiler Anda sendiri, menggunakan tata bahasa C #, dan menggunakan semua token yang ditemukan seperti itu untuk sesuatu yang sewenang-wenang, tidak terkait dengan apa yang didefinisikan dalam spesifikasi bahasa C #. Namun, bahasa yang dihasilkan hanya akan mirip C #, tidak dapat dianggap C #.
ATAU Mapper
88
Anda dapat menggunakan stringtanpa menggunakan direktif untuk Sistem. Anda tidak dapat melakukannya dengan String.
Wilsu
14
Bagi seseorang yang datang dari Algol dan Fortran, diskusi ini menunjukkan ada yang salah dengan itu string. Diperlukan untuk menyingkat System.String, tetapi, sebagai alias, sepertinya cukup, tetapi tidak persis sama. Setelah beberapa tahun C #, meskipun, saya akan mengatakan, adalah aman untuk hanya menggunakan stringdan string.Format()dan tidak khawatir tentang System.String.
Roland
8
@ Sangeeta Apa yang kamu katakan? The System.Stringkelas masih ada, dan stringkata kunci masih merupakan alias untuk itu. Hanya suka System.Int32dan int. Mereka secara harfiah adalah hal yang sama.
Craig

Jawaban:

6106

stringadalah alias dalam C # untuk System.String.
Jadi secara teknis, tidak ada perbedaan. Ini seperti int vs System.Int32 .

Sejauh pedoman, umumnya disarankan untuk menggunakan stringsetiap kali Anda merujuk ke suatu objek.

misalnya

string place = "world";

Demikian juga, saya pikir ini umumnya direkomendasikan untuk digunakan Stringjika Anda perlu merujuk secara khusus ke kelas.

misalnya

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

Ini adalah gaya yang cenderung digunakan Microsoft dalam contoh mereka .

Tampaknya panduan di area ini mungkin telah berubah, karena StyleCop sekarang memberlakukan penggunaan alias khusus C #.

Taman Derek
sumber
163
Jika Anda memutuskan untuk menggunakan StyleCop dan ikuti itu, itu akan mengatakan untuk menggunakan tipe spesifik untuk bahasa. Jadi untuk C # Anda akan memiliki string (bukan String), int (bukan Int32), float (bukan Single) - stylecop.soyuz5.com/SA1121.html
Dominic Zukiewicz
144
Saya selalu menggunakan alias karena saya berasumsi suatu hari nanti mungkin berguna karena mereka bertindak sebagai abstraksi, sehingga implementasi mereka dapat diubah tanpa saya harus tahu.
Rob
37
Visual Studio 2015 mengatakan bahwa String.Format harus diubah menjadi string.Format, jadi saya kira Microsoft akan seperti itu. Saya juga selalu menggunakan String untuk metode statis.
Sami Kuhmonen
32
Ketika saya membaca ini, saya perhatikan beberapa komentar tidak benar. @ DRAirey1 Pada waktunya, Anda akan menemukan bahwa cara lama masih yang terbaik, jika Anda ragu maka saya berani Anda mencoba menulis kode C # tanpa menggunakan Visual Studio. Ini hampir tidak mungkin dan situasi yang muncul dari waktu ke waktu dalam pekerjaan pengembangan web. @Vlad Anda tidak perlu mengimpor apa pun untuk menggunakan String. @ Abhi Komentar Anda tidak ada gunanya dan sama benarnya untuk string.Format(). @ KlitosG Tidak, itu tidak benar. Mereka semua bekerja persis sama.
krowe2
46
Bisakah Anda menambahkan komentar bahwa sebenarnya ada perbedaan? Sebagai contoh: nameof(string)tidak akan mengkompilasi sedangkan nameof(String)akan.
Jeroen Vannevel
3440

Demi kelengkapan, berikut adalah kumpulan informasi terkait ...

Seperti yang telah dicatat orang lain, stringadalah alias untuk System.String. Mereka mengkompilasi ke kode yang sama, sehingga pada waktu eksekusi tidak ada perbedaan apa pun. Ini hanyalah salah satu dari alias di C #. Daftar lengkapnya adalah:

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

Terlepas dari stringdan object, alias semua untuk tipe nilai. decimaladalah tipe nilai, tetapi bukan tipe primitif di CLR. Satu-satunya tipe primitif yang tidak memiliki alias adalah System.IntPtr.

Dalam spec, alias tipe nilai dikenal sebagai "tipe sederhana". Literal dapat digunakan untuk nilai konstan dari setiap tipe sederhana; tidak ada tipe nilai lain yang memiliki bentuk literal tersedia. (Bandingkan ini dengan VB, yang memungkinkan DateTimeliteral, dan juga memiliki alias untuk itu.)

Ada satu keadaan di mana Anda harus menggunakan alias: ketika secara eksplisit menentukan jenis enum yang mendasarinya. Contohnya:

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

Itu hanya soal cara spec mendefinisikan enum deklarasi - bagian setelah usus besar harus menjadi terpisahkan-jenis produksi, yang merupakan salah satu tanda sbyte, byte, short, ushort, int, uint, long, ulong, char... sebagai lawan jenis produksi digunakan oleh deklarasi variabel misalnya. Itu tidak menunjukkan perbedaan lainnya.

Akhirnya, ketika tiba saatnya untuk menggunakan: secara pribadi saya menggunakan alias di mana-mana untuk implementasi, tetapi tipe CLR untuk API apa pun. Ini benar-benar tidak terlalu penting yang Anda gunakan dalam hal implementasi - konsistensi di antara tim Anda bagus, tetapi tidak ada orang lain yang peduli. Di sisi lain, itu benar-benar penting bahwa jika Anda merujuk pada jenis dalam API, Anda melakukannya dengan cara yang netral bahasa. Metode yang disebut ReadInt32tidak ambigu, sedangkan metode yang disebut ReadIntmembutuhkan interpretasi. Penelepon dapat menggunakan bahasa yang mendefinisikan intalias untuk Int16, misalnya. Desainer .NET framework telah mengikuti pola ini, contoh yang bagus ada di BitConverter, BinaryReaderdan Convertkelas.

Jon Skeet
sumber
82
Situasi warisan dengan enum menarik. Bisakah Anda arahkan ke dokumentasi mengapa alias harus digunakan untuk enumerasi? Atau apakah ini bug yang dikenal?
JaredPar
149
Itu ada di bagian 14.1 dari spesifikasi (saya tidak bisa mengutip di sini dengan mudah karena terlalu panjang). Itu tidak secara eksplisit mengatakan bahwa Anda harus menggunakan alias, tetapi alias semacam diperlakukan sebagai jenis mereka sendiri. Itu semua agak aneh.
Jon Skeet
32
@PiPeep Yang lebih mengejutkan dari jumlah besar upvotes adalah jumlah downvotes yang mengejutkan (anggap 5 posting teratas memiliki total lebih dari 2000 upvotes, namun hanya 1 downvote di antara mereka semua). Terutama ketika Anda mempertimbangkan gagasan bahwa selalu ada "pembenci" di komunitas mana pun, saya benar-benar menganggapnya luar biasa.
corsiKa
40
Satu perbedaan yang menarik antara stringdan Stringadalah string' is a keyword in c#, so you can not use it as a variable name.For Ex: string string = "hi"; //compiler error, but String String = "hi"; `dapat diterima, seperti Stringpengidentifikasi bukan kata kunci.
Sanjeev Rai
33
@SanjeevRai: Ya. Anda dapat menggunakan @stringuntuk membuat pengidentifikasi yang berakhir seolah- stringolah. Ini semacam mekanisme melarikan diri.
Jon Skeet
716

Stringsingkatan System.Stringdan itu adalah tipe .NET Framework. stringadalah alias dalam bahasa C # untuk System.String. Keduanya dikompilasi System.Stringdalam IL (Intermediate Language), sehingga tidak ada perbedaan. Pilih apa yang Anda suka dan gunakan itu. Jika Anda kode dalam C #, saya lebih suka stringkarena ini adalah alias tipe C # dan terkenal oleh programmer C #.

Saya dapat mengatakan hal yang sama tentang ( int, System.Int32) dll.

artur02
sumber
3
`Jika Anda kode dalam C #, saya lebih suka string karena ini adalah alias tipe C # dan terkenal oleh programmer C # - kapan seorang C # tidak tahu kerangka NET. +1 seperti yang saya pikir secara umum ini adalah jawaban terbaik, tetapi poin yang saya sebutkan tampak aneh.
MyDaftQuestions
4
Saya pribadi lebih suka menggunakan "Int32", karena langsung menunjukkan kisaran nilai. Bayangkan jika mereka meningkatkan jenis "int" pada sistem yang lebih tinggi. 'int' dalam c tampaknya dipandang sebagai "tipe integer yang paling efisien digunakan oleh prosesor target" , dan didefinisikan sebagai "setidaknya 16 bit". Saya lebih suka konsistensi yang dapat diprediksi di sana, terima kasih banyak.
Nyerguds
2
@MyDaftQuestions saya setuju. Jika ada sesuatu yang masuk akal untuk secara konsisten menggunakan tipe .net karena mereka tidak mengerti bahasa dan jenisnya jelas, tidak tergantung pada bahasa apa pun (apakah saya tahu semua keanehan F # atau VB?).
Peter - Reinstate Monica
5
@Nyerguds Ada dua alasan untuk tidak mengkhawatirkannya. Salah satunya adalah yang intdidefinisikan dalam spesifikasi bahasa C # sebagai integer 32 bit terlepas dari perangkat kerasnya. C #, meskipun warisan bersama dalam kabut waktu, sebenarnya bukan C. Mengubah intbilangan bulat 64 bit akan menjadi perubahan besar dalam spesifikasi dan bahasa. Itu juga akan membutuhkan redefining long, seperti longsaat ini integer 64 bit. Alasan lain untuk tidak khawatir adalah tidak relevan karena tipe tidak akan pernah berubah, tetapi. NET hanya abstrak sehingga 99% dari waktu Anda tidak harus memikirkannya lagi. ;-)
Craig
5
@Craig Saya menggali ke dalam banyak tua format permainan proprietary di mana saya tidak harus berpikir tentang itu sepanjang waktu, meskipun. Dan kemudian menggunakan Int16, Int32dan Int64merupakan banyak lebih transparan dalam kode daripada menggunakan lebih nondescriptive short, intdanlong
Nyerguds
506

Jawaban terbaik yang pernah saya dengar tentang menggunakan alias tipe yang disediakan di C # berasal dari Jeffrey Richter dalam bukunya CLR Via C # . Berikut 3 alasannya:

  • Saya telah melihat sejumlah pengembang bingung, tidak tahu apakah akan menggunakan string atau String dalam kode mereka. Karena dalam C # string (kata kunci) memetakan dengan tepat ke System.String (tipe FCL), tidak ada perbedaan dan keduanya dapat digunakan.
  • Dalam C #, peta panjang ke System.Int64 , tetapi dalam bahasa pemrograman yang berbeda, panjang bisa memetakan ke Int16 atau Int32 . Bahkan, C ++ / CLI sebenarnya memperlakukan selama sebagai Int32 . Seseorang yang membaca kode sumber dalam satu bahasa dapat dengan mudah salah mengartikan maksud kode jika ia terbiasa pemrograman dalam bahasa pemrograman yang berbeda. Bahkan, sebagian besar bahasa bahkan tidak akan memperlakukan lama sebagai kata kunci dan tidak akan mengkompilasi kode yang menggunakannya.
  • FCL memiliki banyak metode yang memiliki nama ketik sebagai bagian dari nama metode mereka. Misalnya, tipe BinaryReader menawarkan metode seperti ReadBoolean , ReadInt32 , ReadSingle , dan seterusnya, dan tipe System.Convert menawarkan metode seperti ToBoolean , ToInt32 , ToSingle , dan sebagainya. Meskipun legal untuk menulis kode berikut, baris dengan float terasa sangat tidak wajar bagi saya, dan tidak jelas bahwa baris tersebut benar:
BinaryReader br = new BinaryReader(...);
float val  = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good

Jadi begitulah. Saya pikir ini semua adalah poin yang sangat bagus. Namun, saya tidak menemukan diri saya menggunakan saran Jeffrey dalam kode saya sendiri. Mungkin saya terlalu terjebak dalam dunia C # saya tetapi akhirnya saya mencoba membuat kode saya terlihat seperti kode kerangka kerja.

Luke Foust
sumber
24
Poin kedua terdengar seperti alasan untuk tidak menggunakan string, intdll.
MauganRa
15
@ MauganRa Dan memang seharusnya begitu, penulis buku mencantumkan alasan-alasan mengapa dia tidak menggunakan alias.
tomi.lee.jones
31
"Jika seseorang membaca kode sumber C # mereka harus menafsirkan panjang sesuai dengan spesifikasi bahasa, bukan spec bahasa lain." Itu sama sekali meleset dari intinya. Bukannya ada yang berniat salah menafsirkan kode, itu hanya mudah bagi otak seseorang untuk melompat ke kesimpulan yang salah ketika suatu tipe memiliki arti yang berbeda dari apa yang dilihat programmer setiap hari dalam konteks lain. Kita semua membuat kesalahan; menggunakan jenis-jenis yang disebutkan secara eksplisit membuat kesalahan-kesalahan itu kecil kemungkinannya.
Darryl
10
+ Alasan-alasan ini meringkas perasaan saya tentang masalah ini. Ketika saya pertama kali mulai coding dalam C # (berasal dari latar belakang Java / C ++ / C) saya pikir alias jelek. Saya masih merasa seperti itu, sayangnya sebagian besar dunia sepertinya tidak setuju dengan saya, atau mereka tidak peduli, jadi gunakan huruf kecil.
gusgorman
8
@jinzai pertanyaannya adalah tentang C #, yang longdidefinisikan sebagai integer 64-bit yang ditandatangani, terlepas dari platform atau kompilernya. Jadi dalam beberapa kasus setidaknya, ya, itu tidak tergantung pada bahasa.
phoog
456

stringadalah kata yang dilindungi undang-undang, tetapi Stringhanya nama kelas. Ini berarti bahwa stringtidak dapat digunakan sebagai nama variabel dengan sendirinya.

Jika karena alasan tertentu Anda menginginkan variabel yang disebut string , Anda hanya akan melihat yang pertama dari kompilasi ini:

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

Jika Anda benar-benar menginginkan nama variabel yang disebut string, Anda dapat menggunakan @awalan:

StringBuilder @string = new StringBuilder();

Perbedaan kritis lainnya: Stack Overflow menyoroti mereka secara berbeda.

Simon_Weaver
sumber
20
Perlu diingat bahwa memanggil lokal @stringbenar-benar tidak ada gunanya, karena nama-nama penduduk lokal hanya ada dalam PDB. Mungkin juga menyebutnya _stringatau sesuatu. Lebih masuk akal untuk hal-hal yang memiliki nama yang dapat diakses melalui refleksi, di mana nama @stringanggota akan berada "string".
Roman Starkov
25
Juga perlu diingat menggunakan kata yang dipesan karena nama variabel sangat tidak tepat.
Elton
7
OP tidak ingin menggunakan String atau string sebagai nama variabel. Mereka meminta penjelasan tentang perbedaan antara Tipe - tipe ini . Jawaban Anda hanya berfungsi untuk menambah lebih banyak kebingungan IMO
Matt Wilko
1
@craig jika Anda sedang menulis perangkat lunak untuk mengajar orang cara mengikat simpul?
Simon_Weaver
5
@Simon_Weaver simpul dalam string? haha bagus. :-) Tentu saja, Anda dapat memilih nama alternatif, seperti utas. Tunggu sebentar ... Doh!
Craig
392

Ada satu perbedaan - Anda tidak dapat menggunakannya Stringtanpa using System;sebelumnya.

user3296
sumber
14
secara default kebanyakan orang menambahkan ini dengan cara apa pun di bagian atas file. VS melakukan ini secara default dalam kebanyakan kasus tidak semua!
IbrarMumtaz
9
Secara default, saya hanya menambahkan usingpernyataan yang saya perlukan, dan secara eksplisit menghapus semua yang tidak saya miliki. Alat Produktivitas Daya> "[x] Hapus dan Format Penggunaan pada save"
JMD
2
@JMD Saya telah memodifikasi file template .cs sehingga bahkan tidak memiliki pernyataan penggunaan di bagian atas! Saya juga mengubah templat kelas menjadi internal sealed.
ErikE
@ JMD Saya benci fitur itu. Terkadang ia membuat perubahan pada file yang tidak tersentuh sehingga membuatnya sulit untuk melihat perubahan apa yang sebenarnya berisi perubahan. Tentu saja saya biasanya menghapus "menggunakan spam", tetapi hanya secara aktif, tidak secara otomatis.
mg30rg
Itu mungkin demikian untuk C #, tetapi tidak semua bahasa .NET. (Powershell mengimpor namespace Sistem secara default.)
FSCKur
312

Sudah dibahas di atas; Namun, Anda tidak dapat menggunakan stringrefleksi; kamu harus menggunakan String.

TraumaPony
sumber
6
Saya tidak mengerti apa arti jawaban ini dan mengapa jawaban itu dibatalkan. Anda bisa menggunakannya typeof(string)dalam refleksi. Contoh satu: if (someMethodInfo.ReturnType == typeof(string)) { ... }Contoh dua: var p = typeof(string).GetProperty("FirstChar", BindingFlags.NonPublic | BindingFlags.Instance);Di mana Anda harus menggunakannya String, bukan string? Jika Anda mencoba hal-hal seperti Type.GetType("String")atau Type.GetType("string"), tidak akan menemukan kelas karena namespace hilang. Jika karena alasan konyol Anda membandingkan .Namesuatu tipe dengan "string"cara case-sensitive, Anda benar.
Jeppe Stig Nielsen
257

System.Stringadalah kelas .NET string - di C # stringadalah alias untuk System.String- jadi saat digunakan keduanya sama.

Adapun pedoman saya tidak akan terlalu macet dan hanya menggunakan mana pun yang Anda suka - ada hal-hal yang lebih penting dalam hidup dan kode akan tetap sama.

Jika Anda menemukan diri sistem di mana perlu membangun untuk menentukan ukuran bilangan bulat yang Anda gunakan dan begitu cenderung digunakan Int16, Int32, UInt16, UInt32dll maka mungkin terlihat lebih alami untuk menggunakan String- dan ketika bergerak di sekitar antara bahasa .net yang berbeda itu mungkin membuat hal-hal lebih dimengerti - kalau tidak saya akan menggunakan string dan int.

Ronnie
sumber
2
Cukup pilih satu dan konsisten. Jika Anda bekerja di suatu tempat dengan gaya rumah, gunakan itu.
Alan B
3
sayangnya gaya adalah preferensi pribadi dan mungkin terlalu mahal untuk diterapkan dalam basis kode besar di beberapa tim tanpa pemilik kode khusus. selalu ada hal-hal yang lebih penting untuk dijaga daripada string vs String. yang membawa kita kembali ke "hal-hal yang lebih penting dalam hidup"
aiodintsov
Ini jelas merupakan hal yang disukai; misalnya: Saya lebih suka menggunakan short, int, ushort, uintbukan Int16, dll Terutama karena ini adalah bagaimana saya belajar. Memang, Int16lebih mudah untuk segera memahami bagi mereka yang kurang pengalaman. +1 Dari saya!
Candleshark
211

Saya lebih suka .NETjenis huruf besar (daripada alias) untuk alasan pemformatan. The .NETjenis berwarna sama dengan jenis objek lain (jenis nilai adalah objek yang tepat, setelah semua).

Kata kunci bersyarat dan kontrol (seperti if,, switchdan return) adalah huruf kecil dan berwarna biru tua (secara default). Dan saya lebih suka tidak memiliki perbedaan pendapat dalam penggunaan dan format.

Mempertimbangkan:

String someString; 
string anotherString; 
StuartLC
sumber
11
Apakah Anda juga menulis kode seperti: Int32 i = 1; Daripada int i = 1; ? Tampaknya tidak konsisten untuk tidak menggunakan alias string ketika itu tersedia.
bytedev
29
@nashwan: sebenarnya, ya, saya menggunakan Int32 i=1;intstead int i = 1; saya menemukan yang pertama lebih mudah dibaca untuk maksud saya: yaitu bahwa saya ingin integer 32 bit yang ditandatangani.
NotMe
5
Yah saya kira itu semua tergantung apakah pengembang berpikir mereka sedang menulis kode C # (string) atau .NET code (String). Secara pribadi saya pikir saya sedang menulis C # (dan itu C # yang menggunakan .NET).
bytedev
7
@Alex: maksud saya adalah saya lebih suka untuk lebih spesifik dalam pengkodean saya untuk menghapus ambiguitas.
NotMe
22
Di ujung lain mutlak spektrum, saya hampir selalu hanya menggunakanvar
tic
193

stringdan Stringidentik dalam semua hal (kecuali huruf besar "S"). Tidak ada implikasi kinerja.

Huruf kecil stringlebih disukai di sebagian besar proyek karena penyorotan sintaksis

TheSoftwareJedi
sumber
Jeffrey Richter merekomendasikan penggunaan tipe CLR dalam semua kasus (CLR via C #) untuk menghindari jenis kebingungan yang terjadi di sini.
Josh
Jelas, apakah Anda menggunakan S atau s, itu akan menyebabkan pertanyaan ini, jadi pilihlah Richter. ;)
Brad Wilson
Richter berarti bahwa string seharusnya tidak menjadi pilihan - Microsoft seharusnya tidak memilikinya dalam bahasa tersebut. Anda tidak dapat memilih Richter - dia seorang legenda! :)
Joe Ratzer
1
Saya setuju bahwa mungkin lebih baik tidak memiliki alias sama sekali. Tetapi mengingat bahwa kita memilikinya, saya pikir tidak masalah untuk menggunakannya (tetapi tidak dalam nama metode dll.)
Jon Skeet
10
"string" tidak sama dengan "String". Apakah berarti "System.String". Jadi jika Anda menggunakan "String" Anda harus memasukkan "using System" untuk memasukkan namespace
ThiagoAlves
186

C # adalah bahasa yang digunakan bersama dengan CLR.

string adalah tipe dalam C #.

System.String adalah tipe dalam CLR.

Ketika Anda menggunakan C # bersama dengan CLR stringakan dipetakan ke System.String.

Secara teoritis, Anda bisa mengimplementasikan kompiler C # yang menghasilkan bytecode Java. Implementasi masuk akal dari kompiler ini mungkin akan memetakan stringke java.lang.Stringdalam rangka untuk beroperasi dengan runtime library Java.

Rasmus Faber
sumber
1
stringbukan tipe dalam C #; itu adalah kata khusus yang memetakan ke suatu jenis dalam CLR.
CesarGon
@CesarGon: Menurut ECMA-334, bagian 8.2.1: "C # menyediakan serangkaian tipe yang telah ditentukan [...] Jenis referensi yang telah ditetapkan adalah objek dan string."
Rasmus Faber
10
Menurut ECMA-334, bagian 9.4.3, "string" adalah kata kunci. :-) Saya setuju dengan Anda bahwa "string" adalah tipe jika Anda fokus pada semantik, tapi saya akan mengatakan itu adalah kata kunci (yaitu kata yang dipesan) jika Anda fokus pada sintaksis. Standar ini mendukung kedua sudut pandang (mungkin terlalu ambigu!). Bagi saya, OP adalah tentang sintaksis, jadi saya cenderung fokus pada sintaksis ketika saya melihat jawaban, tetapi saya juga mengerti maksud Anda. Selanjutnya, jawaban Anda, sebagaimana adanya, dapat diartikan sebagai berarti bahwa ada dua jenis yang berbeda: string dan String, ketika itu tidak terjadi. Satu adalah pemetaan ke yang lain.
CesarGon
Mari kita perjelas tentang ini. 'string' adalah alias khusus. Ini bukan tipe data yang benar. Itu adalah sesuatu yang menunjuk pada sesuatu yang lain. Anda dapat menghapus semua alias ini (atau tidak pernah menggunakannya) dan memiliki bahasa pemrograman yang sangat baik.
Quarkly
169

Video YouTube ini menunjukkan secara praktis perbedaannya.

Tapi sekarang untuk jawaban tekstual yang panjang.

Ketika kita berbicara tentang .NETada dua hal yang berbeda satu ada .NETkerangka kerja dan yang lainnya ada bahasa ( C#, VB.NETdll) yang menggunakan kerangka itu.

masukkan deskripsi gambar di sini

" System.String" alias "String" (huruf kapital "S") adalah .NETtipe data kerangka kerja sedangkan "string" adalah C#tipe data.

masukkan deskripsi gambar di sini

Singkatnya "String" adalah alias (hal yang sama disebut dengan nama yang berbeda) dari "string". Jadi secara teknis kedua pernyataan kode di bawah ini akan memberikan hasil yang sama.

String s = "I am String";

atau

string s = "I am String";

Dengan cara yang sama ada alias untuk tipe data c # lainnya seperti yang ditunjukkan di bawah ini: -

objek: System.Object, String: System.String, bool: System.Boolean, byte: System.Byte, sbyte: System.SByte, pendek: System.Int16dan sebagainya

Sekarang pertanyaan jutaan dolar dari sudut pandang programmer Jadi kapan harus menggunakan "String" dan "string"?

Hal pertama untuk menghindari kebingungan gunakan salah satunya secara konsisten. Tetapi dari perspektif praktik terbaik ketika Anda melakukan deklarasi variabel, ada baiknya menggunakan "string" (kecil "s") dan ketika Anda menggunakannya sebagai nama kelas maka "String" (huruf kapital "S") lebih disukai.

Dalam kode di bawah ini, sisi kiri adalah deklarasi variabel dan dinyatakan menggunakan "string". Di sisi kanan kita memanggil metode sehingga "String" lebih masuk akal.

string s = String.ToUpper() ;
Shivprasad Koirala
sumber
25
"Singkatnya" String "adalah alias (hal yang sama disebut dengan nama yang berbeda) dari" string "". Ini tidak benar: aliasnya adalah "string".
Xavier Egea
3
ketika Anda melakukan deklarasi variabel itu baik untuk menggunakan "string" ("s" kecil) dan ketika Anda menggunakannya sebagai nama kelas maka "String" (huruf kapital "S") lebih disukai. Konvensi ini tampaknya tidak lagi valid: jika Anda menggunakan Visual Studio 2015 dan mencoba menulisnya Stringmenyarankan Anda untuk "menyederhanakan kode Anda", membawanya ke string...
Massimiliano Kraus
166

Huruf kecil stringadalah alias untuk System.String. Mereka sama di C#.

Ada perdebatan apakah Anda harus menggunakan jenis Sistem ( System.Int32, System.String, dll) jenis atau C# aliases( int, string, dll). Saya pribadi percaya Anda harus menggunakan C# aliases, tapi itu hanya preferensi pribadi saya.

urini
sumber
4
Itu masalahnya, mereka bukan alias 'C #', mereka adalah alias 'C'. Tidak ada 'string' atau 'int' asli dalam bahasa C #, hanya gula sintaksis.
Quarkly
16
tidak yakin dari mana "C" berasal dari sini, karena spesifikasi bahasa C # 5 berbunyi "String kata kunci hanyalah alias untuk System.String kelas yang telah ditentukan." di halaman 85, paragraf 4.2.4. Semua bahasa tingkat tinggi adalah gula sintaksis di atas set instruksi dan bytecode CPU.
aiodintsov
157

stringhanyalah alias untuk System.String. Kompiler akan memperlakukan mereka secara identik.

Satu-satunya perbedaan praktis adalah penyorotan sintaksis seperti yang Anda sebutkan, dan bahwa Anda harus menulis using Systemjika Anda menggunakannya String.

Hallgrim
sumber
Anda tidak perlu awalan Sistem untuk menggunakan String.
Joe Ratzer
18
Anda harus menyertakan using Systemsaat menggunakan String, jika tidak Anda mendapatkan kesalahan berikut:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)
Ronald
144

Keduanya sama. Tapi dari perspektif pedoman pengkodean lebih baik digunakan stringdaripada String. Inilah yang umumnya digunakan pengembang. mis. alih-alih menggunakan, Int32kami menggunakan intapa intadanya alias untukInt32

FYI "String kata kunci hanyalah alias untuk kelas yang telah ditentukan System.String." - C # Bahasa Spesifikasi 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx

Pradeep Kumar Mishra
sumber
121

Seperti yang dikatakan orang lain, mereka sama. Aturan StyleCop, secara default, akan menegakkan Anda untuk menggunakan stringsebagai gaya kode C # praktek terbaik, kecuali ketika referensi System.Stringfungsi statis, seperti String.Format, String.Join, String.Concat, dll ...

Lloyd Cotten
sumber
4
Saya tidak menyadari bahwa StyleCop akan menandai penggunaan String - kecuali untuk metode statis. Saya pikir itu hebat karena itu adalah bagaimana saya selalu menggunakannya: string untuk tipe deklarasi dan String ketika saya mengakses anggota statis.
Goyuix
102

Jawaban baru setelah 6 tahun dan 5 bulan (penundaan).

Meskipun stringkata kunci C # yang dilindungi undang-undang yang selalu memiliki makna tetap, Stringhanyalah pengidentifikasi biasa yang dapat merujuk pada apa pun. Bergantung pada anggota tipe saat ini, namespace saat ini dan usingarahan yang diterapkan serta penempatannya, Stringdapat berupa nilai atau tipe yang berbeda global::System.String.

Saya akan memberikan dua contoh di mana usingarahan tidak akan membantu .


Pertama, ketika Stringadalah nilai dari jenis saat ini (atau variabel lokal):

class MySequence<TElement>
{
  public IEnumerable<TElement> String { get; set; }

  void Example()
  {
    var test = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
  }
}

Di atas tidak akan dikompilasi karena IEnumerable<>tidak memiliki anggota non-statis yang dipanggil Format, dan tidak ada metode ekstensi yang berlaku. Dalam kasus di atas, masih mungkin untuk digunakan Stringdalam konteks lain di mana jenis adalah satu-satunya kemungkinan secara sintaksis. Misalnya String local = "Hi mum!";bisa OK (tergantung namespace dan usingarahan).

Lebih buruk: Mengatakan String.Concat(someSequence)kemungkinan akan (tergantung pada usings) pergi ke metode ekstensi Linq Enumerable.Concat. Itu tidak akan pergi ke metode statis string.Concat.


Kedua, kapan tipeString lain , bersarang di dalam tipe saat ini:

class MyPiano
{
  protected class String
  {
  }

  void Example()
  {
    var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
    String test2 = "Goodbye";
  }
}

Tidak ada pernyataan dalam Examplemetode yang dikompilasi. Berikut Stringselalu piano tali , MyPiano.String. Tidak ada anggota ( staticatau tidak) Formatada di sana (atau diwarisi dari kelas dasarnya). Dan nilainya "Goodbye"tidak dapat dikonversi ke dalamnya.

Jeppe Stig Nielsen
sumber
4
Saya kira seseorang yang jahat bisa: using String = System.Int32; using Int32 = System.String; dan kemudian menghitung serangga.
Steve
7
Ini adalah jawaban yang benar. stringadalah System.String. Stringbisa apa saja.
Dave Cousineau
Setuju @DaveCousineau - itulah gunanya alias. Anda bisa membuat Stringtipe lain yang tidak akan diatur ke objek System.String. Lihat: blog.paranoidcoding.com/2019/04/08/...
Kristopher
"Kata kunci tersebut stringmemiliki makna konkret dalam C #. Ini adalah tipe System.Stringyang ada dalam rakitan runtime inti. Runtime secara intrinsik memahami tipe ini dan menyediakan kapabilitas yang diharapkan pengembang stringsdalam. NET. Keberadaannya sangat penting untuk C # sehingga jika tipe itu tidak tidak ada kompilator yang akan keluar sebelum mencoba untuk mengurai sebaris kode. Oleh karena itu stringmemiliki makna yang tepat, tidak ambigu dalam kode C #. Identifier Stringmeskipun tidak memiliki makna konkret dalam C #. Ini adalah pengidentifikasi yang melewati semua aturan pencarian nama sebagai Widget,, Studentdll ... "
Kristopher
3
Diskussed on Meta: meta.stackoverflow.com/questions/385304/…
Patrick Artner
100

Menggunakan tipe Sistem memudahkan untuk melakukan porting antara C # dan VB.Net, jika Anda menyukai hal-hal seperti itu.

Ismail
sumber
1
Konversi antara C # dan VB.NET cukup mudah. developerfusion.com/tools/convert/vb-to-csharp
berikan
88

Terhadap apa yang tampaknya menjadi praktik umum di kalangan programmer lain, saya lebih suka Stringlebih string, hanya untuk menyoroti fakta bahwa Stringadalah tipe referensi, seperti Jon Skeet disebutkan.

RolandK
sumber
82

stringadalah alias (atau singkatan) dari System.String. Itu berarti, dengan mengetik yang stringkami maksud System.String. Anda dapat membaca lebih lanjut di tautan think: 'string' adalah alias / singkatan dari System.String.

JeeShen Lee
sumber
78

Saya hanya ingin menambahkan ini ke jawaban lfousts, dari buku Ritchers:

Spesifikasi bahasa C # menyatakan, "Sebagai masalah gaya, penggunaan kata kunci lebih disukai daripada penggunaan nama tipe sistem yang lengkap." Saya tidak setuju dengan spesifikasi bahasa; Saya lebih suka menggunakan nama tipe FCL dan sepenuhnya menghindari nama tipe primitif. Bahkan, saya berharap bahwa kompiler bahkan tidak menawarkan nama tipe primitif dan memaksa pengembang untuk menggunakan nama tipe FCL sebagai gantinya. Inilah alasan saya:

  • Saya telah melihat sejumlah pengembang bingung, tidak tahu apakah akan menggunakan string atau String dalam kode mereka. Karena dalam string C # (kata kunci) memetakan dengan tepat ke System.String (tipe FCL), tidak ada perbedaan dan keduanya dapat digunakan. Demikian pula, saya pernah mendengar beberapa pengembang mengatakan bahwa int mewakili integer 32-bit ketika aplikasi berjalan pada OS 32-bit dan bahwa itu mewakili integer 64-bit ketika aplikasi berjalan pada OS 64-bit. Pernyataan ini benar-benar salah: di C #, int selalu memetakan ke System.Int32 , dan karena itu mewakili integer 32-bit terlepas dari OS yang dijalankan oleh kode. Jika programmer akan menggunakanInt32 dalam kode mereka, maka potensi kebingungan ini juga dihilangkan.

  • Dalam C #, peta panjang ke System.Int64 , tetapi dalam bahasa pemrograman yang berbeda, panjang bisa memetakan ke Int16 atau Int32 . Bahkan, C ++ / CLI memperlakukan selama sebagai Int32 . Seseorang yang membaca kode sumber dalam satu bahasa dapat dengan mudah salah mengartikan maksud kode jika ia terbiasa pemrograman dalam bahasa pemrograman yang berbeda. Bahkan, sebagian besar bahasa bahkan tidak akan memperlakukan lama sebagai kata kunci dan tidak akan mengkompilasi kode yang menggunakannya.

  • FCL memiliki banyak metode yang memiliki nama ketik sebagai bagian dari nama metode mereka. Misalnya, tipe BinaryReader menawarkan metode seperti ReadBoolean , ReadInt32 , ReadSingle , dan seterusnya, dan tipe System.Convert menawarkan metode seperti ToBoolean , ToInt32 , ToSingle , dan sebagainya. Meskipun legal untuk menulis kode berikut, baris dengan float terasa sangat tidak wajar bagi saya, dan tidak jelas bahwa baris tersebut benar:

    BinaryReader br = new BinaryReader(...);
    float val = br.ReadSingle(); // OK, but feels unnatural
    Single val = br.ReadSingle(); // OK and feels good
  • Banyak programmer yang menggunakan C # secara eksklusif cenderung lupa bahwa bahasa pemrograman lain dapat digunakan terhadap CLR, dan karena itu, C # -isms merayap ke dalam kode perpustakaan kelas. Misalnya, Microsoft FCL hampir secara eksklusif ditulis dalam C # dan pengembang di tim FCL sekarang telah memperkenalkan metode ke perpustakaan seperti Array 's GetLongLength , yang mengembalikan nilai Int64 yang panjang dalam C # tetapi tidak dalam bahasa lain (seperti C ++ / CLI). Contoh lain adalah System.Linq.Enumerable ‘s LongCount metode.

Saya tidak mendapatkan pendapatnya sebelum saya membaca paragraf lengkap.

Otiel
sumber
72

String ( System.String) adalah kelas di pustaka kelas dasar. string (huruf kecil) adalah karya yang disediakan di C # yang merupakan alias untuk System.String. Int32 vs int adalah situasi yang sama Boolean vs. bool. Kata kunci spesifik bahasa C # ini memungkinkan Anda untuk mendeklarasikan primitif dalam gaya yang mirip dengan C.

Joe Alfano
sumber
67

Stringbukan kata kunci dan dapat digunakan sebagai Identifier sedangkan stringkata kunci dan tidak dapat digunakan sebagai Identifier. Dan dalam sudut pandang fungsi keduanya sama.

pengguna576533
sumber
67

Ini masalah konvensi, sungguh. stringhanya lebih mirip gaya C / C ++. Konvensi umum adalah untuk menggunakan cara pintas apa pun yang telah disediakan bahasa pilihan Anda (int / Int untuk Int32). Ini berlaku untuk "objek" dan decimaljuga.

Secara teoritis ini dapat membantu untuk port kode ke beberapa standar 64-bit di masa depan di mana "int" mungkin berarti Int64, tapi bukan itu intinya, dan saya akan mengharapkan panduan upgrade untuk mengubah intreferensi apa pun untuk Int32tetap aman.

Mel
sumber
66

Datang terlambat ke pesta: Saya menggunakan tipe CLR 100% dari waktu (well, kecuali jika dipaksa untuk menggunakan tipe C #, tapi saya tidak ingat kapan terakhir kali itu).

Saya awalnya mulai melakukan ini tahun lalu, sesuai buku CLR oleh Ritchie. Masuk akal bagi saya bahwa semua bahasa CLR pada akhirnya harus dapat mendukung set tipe CLR, jadi menggunakan tipe CLR sendiri memberikan kode yang lebih jelas, dan mungkin lebih "dapat digunakan kembali".

Sekarang saya sudah melakukannya selama bertahun-tahun, itu kebiasaan dan saya suka warna yang ditunjukkan VS untuk tipe CLR.

Satu-satunya downer nyata adalah bahwa lengkapi-otomatis menggunakan tipe C #, jadi saya akhirnya mengetik ulang tipe yang dihasilkan secara otomatis untuk menentukan tipe CLR.

Juga, sekarang, ketika saya melihat "int" atau "string", itu hanya terlihat sangat salah bagi saya, seperti saya sedang melihat kode C tahun 1970-an.

Michael Ray Lovett
sumber
49

Tidak ada perbedaan.

Kata kunci C # stringmemetakan untuk tipe .NET System.String- ini adalah alias yang mempertahankan konvensi penamaan bahasa.

Demikian pula intpeta untuk System.Int32.

Oded
sumber
Dalam build 64 bit, int maps ke System.Int64 (8 bytes), dalam build 32 bit memetakannya ke System.Int32 (4 bytes)
Alex
1
IntPtr dan UIntPtr adalah satu-satunya jenis yang mengubah ukuran berdasarkan platform (mengabaikan jenis penunjuk aktual seperti int*dan jenis yang terdiri dari [U] IntPtrs atau penunjuk aktual).
P Daddy
45

Ada kutipan tentang masalah ini dari buku Daniel Solis .

Semua tipe standar telah dipetakan langsung ke tipe .NET yang mendasarinya. Nama tipe C # (string) hanyalah alias untuk tipe .NET (String atau System.String), jadi menggunakan nama .NET berfungsi dengan baik secara sintaksis, meskipun ini tidak disarankan. Di dalam program C #, Anda harus menggunakan nama C # daripada nama .NET.

pengguna2771704
sumber
41

string adalah kata kunci, dan Anda tidak dapat menggunakan string sebagai pengidentifikasi.

String bukan kata kunci, dan Anda dapat menggunakannya sebagai pengidentifikasi:

Contoh

string String = "I am a string";

Kata kunci string adalah alias untuk System.Stringselain dari masalah kata kunci, keduanya persis sama.

 typeof(string) == typeof(String) == typeof(System.String)
CoreDeveloper
sumber
2
Satu-satunya perbedaan kecil adalah bahwa jika Anda menggunakan kelas String, Anda perlu mengimpor System namespace di atas file Anda, sedangkan Anda tidak harus melakukan ini ketika menggunakan kata kunci string.
Uttam
Ada beberapa kasus penggunaan sederhana di mana pernyataan kesetaraan akan gagal ... Seperti mendefinisikan string panggilan tipe dalam bla namespace dan mengimpor namespace ke dalam file di mana pernyataan kesetaraan berjalan.
rick
40

Ya, tidak ada perbedaan di antara mereka, sama seperti booldan Boolean.

Coder
sumber
40

@JaredPar (pengembang pada kompiler C # dan pengguna SO yang produktif!) Menulis posting blog yang bagus tentang masalah ini. Saya pikir layak untuk dibagikan di sini. Ini adalah perspektif yang bagus tentang masalah kita.

stringvs Stringbukan debat gaya

[...]

Kata kunci stringmemiliki makna konkret dalam C #. Ini adalah tipe System.Stringyang ada dalam perakitan runtime inti. Runtime secara intrinsik memahami tipe ini dan menyediakan kapabilitas yang diharapkan pengembang untuk string dalam .NET. Keberadaannya sangat penting bagi C # sehingga jika tipe itu tidak ada, kompiler akan keluar sebelum mencoba untuk menguraikan baris kode. Karenanya stringmemiliki makna yang tepat dan tidak ambigu dalam kode C #.

Identifier Stringtidak memiliki arti konkret dalam C #. Ini adalah pengidentifikasi yang melewati semua aturan pencarian nama seperti Widget,, Studentdll ... Itu bisa mengikat string atau bisa mengikat ke jenis di majelis lain seluruhnya yang tujuannya mungkin sama sekali berbeda dari string. Lebih buruk lagi dapat didefinisikan sedemikian rupa sehingga kode seperti String s = "hello"; terus mengkompilasi.

class TricksterString { 
  void Example() {
    String s = "Hello World"; // Okay but probably not what you expect.
  }
}

class String {
  public static implicit operator String(string s) => null;
}

Arti sebenarnya Stringakan selalu tergantung pada resolusi nama. Itu artinya tergantung pada semua file sumber dalam proyek dan semua jenis yang ditentukan dalam semua rujukan yang direferensikan. Singkatnya itu membutuhkan sedikit konteks untuk mengetahui apa artinya.

Benar bahwa dalam sebagian besar kasus Stringdan stringakan mengikat ke jenis yang sama. Tetapi menggunakan Stringpengembang diam berarti membiarkan program mereka untuk interpretasi di tempat-tempat di mana hanya ada satu jawaban yang benar. Ketika Stringmengikat ke jenis yang salah itu dapat meninggalkan pengembang debug selama berjam-jam, pengarsipan bug pada tim kompiler dan umumnya membuang-buang waktu yang bisa diselamatkan dengan menggunakan string.

Cara lain untuk memvisualisasikan perbedaan adalah dengan sampel ini:

string s1 = 42; // Errors 100% of the time  
String s2 = 42; // Might error, might not, depends on the code

Banyak yang akan berpendapat bahwa sementara ini informasi yang akurat secara teknis, penggunaannya Stringmasih baik karena sangat jarang bahwa basis kode akan menentukan jenis nama ini. Atau bahwa ketika Stringdidefinisikan itu adalah pertanda basis kode yang buruk.

[...]

Anda akan melihat bahwa Stringdidefinisikan untuk sejumlah tujuan yang sepenuhnya valid: pembantu refleksi, pustaka serialisasi, pustaka, protokol, dll. Untuk pustaka ini Stringvs. stringmemiliki konsekuensi nyata tergantung pada tempat kode digunakan.

Jadi ingat ketika Anda melihat perdebatan Stringvs. stringini tentang semantik, bukan gaya. Memilih string memberikan makna yang tajam untuk basis kode Anda. Memilih Stringtidak salah tetapi membiarkan pintu terbuka untuk kejutan di masa depan.

Catatan: Saya menyalin / menempel sebagian besar posting blog karena alasan arsip. Saya mengabaikan beberapa bagian, jadi saya sarankan untuk melewati dan membaca posting blog jika Anda bisa.

aloisdg
sumber